Python 使用装饰器 decorator 修改函数行为
使用装饰器修改函数行为
Python中装饰器(decorator)的概念基于 Decorator 设计模式,这是一种结构化设计模式。此模式允许您向对象添加新行为,而无需更改对象实现中的任何内容。这个新行为被添加到特殊的包装器对象中。
在 Python 中,装饰器是一种特殊的高阶函数,它使开发者能够在现有函数(或方法)中添加新功能,而无需添加或更改函数中的任何内容。通常,这些装饰器被添加到函数定义之前。装饰器可用于实现应用程序的许多功能,但在数据验证、日志记录、缓存、调试、加密和事务管理等方面尤其流行。
在 Python 中,任何实现了特殊方法 __call__()
的对象,都被称作可调用对象。因此,从最基本的意义上讲,装饰器就是一个返回可调用对象的可调用对象。在 Python 中,一些事物都是对象,函数也是对象。
这里,只以讲解函数返回函数为例。
基本上,装饰器接收一个函数,添加一些功能并返回一个可调用对象。下面的代码演示了一个 add_timestamps
装饰器,它返回了一个内部函数。内部函数在执行作为参数的函数之前和之后,输出当前时间:
from datetime import datetime
def add_timestamps(myfunc):
def _add_timestamps():
print(datetime.now())
myfunc()
print(datetime.now())
return _add_timestamps
@add_timestamps
def hello_world():
print('Hello World!')
hello_world()
上面的代码的输出结果是:
2024-12-30 14:54:17.568101
Hello World!
2024-12-30 14:54:17.568101
在这个例子中, @
符号用来装饰函数,它等价于:
hello = add_timestamps(hell_world)
hello()
这就是 Python 解释器在看到 @
符号之后做的事情——我们显示地调用了装饰器函数add_timestmaps
,传递给它一个hello_world
,它返回了它的内部函数。内部函数在被装饰的函数hell_world
的功能上,添加了新功能。
还有一个问题。我们在调试程序的时候,需要更详细的函数调用信息,然而,使用了装饰器后,当我们在被装饰的函数上调用 help
函数时,或者查看 __doc__
和 __name__
属性时,我们得到的,都不是被装饰函数的信息:
from datetime import datetime
def add_timestamps(myfunc):
def _add_timestamps():
print(datetime.now())
myfunc()
print(dateti