装饰器是一种Python语言特性,可以动态地修改类或函数的行为。在Python中,函数和类都可以作为一等公民被传递、返回或赋予变量,成为一等公民最重要的就是能够在运行时动态创建函数和类。
让我们从最基本的例子开始,然后一步步扩展。
首先,我们定义一个名为 add
的函数,它将两个数字相加并返回结果:
def add(x, y):
return x + y
print(add(2, 3)) # 输出 5
AI 代码解读
这是一个非常普通的函数。我们现在想要为该函数添加一些额外的功能,例如每次调用该函数时都记录一下运行时间。
我们可以通过以下方式来手动添加记录时间的代码:
import time
def add(x, y):
start_time = time.time()
result = x + y
end_time = time.time()
print("函数add的运行时间为:", end_time - start_time)
return result
print(add(2, 3)) # 输出 5 和 "函数add的运行时间为:xxx"
AI 代码解读
代码中我们导入了 time
模块,然后在函数调用前记录了起始时间,函数调用结束后又记录了一个结束时间,两者相减得到运行时间,并打印出来。
但是这种方式有一些缺点,这需要手动修改每个函数的代码,这样很快就会变得繁琐,同时也会影响函数的可读性。此时,装饰器就可以发挥作用。
我们定义一个名为 timed
的装饰器函数,函数的作用是计算包装函数的运行时间并输出执行结果和运行时间。
import time
# 定义装饰器
def timed(function):
def wrapper(*args, **kwargs):
start_time = time.time()
result = function(*args, **kwargs)
end_time = time.time()
print(f"函数 {function.__name__}的运行时间为:{end_time - start_time:.4f} 秒。")
return result
return wrapper
# 使用装饰器
@timed
def add(x, y):
return x + y
print(add(2, 3)) # 输出 5 和 "函数add的运行时间为:xxx"
AI 代码解读
我们看一下 timed
函数的实现,它定义了一个内部函数 wrapper
,并返回该函数。wrapper
函数接收任意数量的位置和关键字参数,并且调用被装饰的函数,获得它的结果。然后Wrapper计算并打印该函数的运行时间,并通过 return
语句返回函数的结果。
使用装饰器时,我们可以使用 @
符号将装饰器名称放在要装饰的函数之前,如 @timed
。
现在我们可以用同样的方式来装饰其他函数,以自动记录它们的运行时间:
@timed
def sub(x, y):
return x - y
print(sub(10, 3)) # 输出 7 和 "函数sub的运行时间为:xxx"
AI 代码解读
当我们调用 add()
或 sub()
时,就会默认使用 timed()
函数装饰,输出函数运行的时间。
这就是一个装饰器的实现方式,通过装饰器,我们可以不修改原函数,来动态地添加一些额外的功能,达到代码复用的目的。