Python 装饰器
装饰器允许你为函数添加额外的行为,而无需更改函数的代码。
装饰器是一个函数,它接受另一个函数作为输入,并返回一个新函数。
Basic Decorator
先定义装饰器,然后在函数上方使用 @decorator_name 应用它。
实例
一个基本的装饰器,用于将装饰函数的返回值转换为大写。
def changecase(func):
def myinner():
return func().upper()
return myinner
@changecase
def myfunction():
return "Hello Sally"
print(myfunction())
亲自试一试 »
通过将 @changecase 直接放在函数定义上方,函数 myfunction 就被 changecase 函数"装饰"了。
函数 changecase 是装饰器。
函数 myfunction 是被装饰的函数。
多次调用装饰器
装饰器可以多次调用。只需将装饰器放在要装饰的函数上方即可。
实例
在两个函数上使用 @changecase 装饰器:
def changecase(func):
def myinner():
return func().upper()
return myinner
@changecase
def myfunction():
return "Hello Sally"
@changecase
def otherfunction():
return "I am speed!"
print(myfunction())
print(otherfunction())
亲自试一试 »
装饰函数中的参数
需要参数的函数也可以被装饰,只需确保将参数传递给包装函数即可:
实例
带参数的函数也可以被装饰:
def changecase(func):
def myinner(x):
return func(x).upper()
return myinner
@changecase
def myfunction(nam):
return "Hello " + nam
print(myfunction("John"))
亲自试一试 »
*args 和 **kwargs
实例
def changecase(func):
def myinner(*args, **kwargs):
return func(*args, **kwargs).upper()
return myinner
@changecase
def myfunction(nam):
return "Hello " + nam
print(myfunction("John"))
亲自试一试 »
带参数的装饰器
装饰器可以通过添加额外的包装层来接受自己的参数。
实例
一个装饰器工厂,它接受一个参数并根据参数值转换大小写。
def changecase(n):
def changecase(func):
def myinner():
if n == 1:
a = func().lower()
else:
a = func().upper()
return a
return myinner
return changecase
@changecase(1)
def myfunction():
return "Hello Linus"
print(myfunction())
亲自试一试 »
多个装饰器
你可以在一个函数上使用多个装饰器。
这可以通过将装饰器调用顺序依次排列来实现。
装饰器会按照指定的顺序调用。
示例
一个装饰器用于将所有内容转换为大写,另一个用于添加问候语:
def changecase(func):
def myinner():
return func().upper()
return myinner
def addgreeting(func):
def myinner():
return "Hello " + func() + " Have a good day!"
return myinner
@changecase
@addgreeting
def myfunction():
return "Tobias"
print(myfunction())
亲自试一试 »
保留函数元数据
Python 中的函数具有元数据,可以使用 __name__ 和 __doc__ 属性访问这些元数据。
实例
通常,函数名称可以通过 __name__ 属性返回:
def myfunction():
return "Have a great day!"
print(myfunction.__name__)
亲自试一试 »
但是,当一个函数被装饰器修饰时,原始函数的元数据就会丢失。
实例
尝试从装饰器修饰的函数中返回名称,你会发现结果不一样:
def changecase(func):
def myinner():
return func().upper()
return myinner
@changecase
def myfunction():
return "Have a great day!"
print(myfunction.__name__)
亲自试一试 »
为了解决这个问题,Python 提供了一个名为 functools.wraps 的内置函数,可以用来保留原始函数的名称和文档字符串。
实例
导入 functools.wraps 以保留原始函数名和文档字符串。
import functools
def changecase(func):
@functools.wraps(func)
def myinner():
return func().upper()
return myinner
@changecase
def myfunction():
return "Have a great day!"
print(myfunction.__name__)
亲自试一试 »

