理解Python中的装饰器
更新时间:2023-12-07什么是装饰器?
装饰器是Python中一种特殊的语法,它允许开发人员修改或扩展函数或类的行为。简单来说,装饰器是一个可以接受一个函数并返回一个函数的函数。装饰器可以用于面向对象编程的类的方法和属性,也可以用于模块级别的函数和方法,还可以用于Decorated Function的修饰或装饰。例如,以下是使用Python装饰器的代码:
def my_decorator(f):
def wrapper():
print("Before function execution")
f()
print("After function execution")
return wrapper
@my_decorator
def say_hello():
print("Hello World")
say_hello()
在上面的代码中,定义了一个my_decorator函数,它接受一个函数作为参数并返回一个封装的函数wrapper,wrapper函数在函数执行前后打印一些内容。这个 @my_decorator 语法是 Python 的语法糖, 它等同于下面这个简单的赋值语句:
say_hello = my_decorator(say_hello)
如何使用装饰器?
使用装饰器很简单,只需要在装饰器函数之上添加 @ 符号,后面跟着装饰器的名称。当我们调用被修饰的函数时,实际上是在调用装饰器,而装饰器返回的函数会被执行。例如,以下代码展示了如何给一个函数添加装饰器:
def my_decorator(f):
def wrapper():
print("Before function execution")
f()
print("After function execution")
return wrapper
@my_decorator
def say_hello(name):
print(f"Hello, {name}!")
say_hello("John")
运行此代码将会报错,因为 decorated 函数通过 @my_decorator 装饰器中的嵌套函数 wrapper 来调用. 所以,这个装饰器函数需要返回一个接受任意个参数的函数. 所以,我们再修改一下 my_decorator 函数:
def my_decorator(f):
def wrapper(*args, **kwargs):
print("Before function execution")
f(*args, **kwargs)
print("After function execution")
return wrapper
@my_decorator
def say_hello(name):
print(f"Hello, {name}!")
say_hello("John")
在上面的代码中,首先定义了一个名为 my_decorator 的装饰器函数,它接收一个函数作为参数,返回一个新的封装后的函数 wrapper。然后,使用 @ 符号将装饰器应用到函数 say_hello 上。最后,调用 say_hello 函数,被装饰器包装后的函数会被执行。
装饰器的应用场景
装饰器通常用于以下场景: - 认证和授权:使用装饰器来限制对某一资源的访问,例如访问某些API时需要添加Token或者Session等身份验证信息。 - 记录日志:使用装饰器来记录函数的执行过程,例如记录函数的名称、参数和返回值。 - 缓存:使用装饰器来缓存函数的输出结果,以减少重复执行相同操作的时间。 - 测量函数执行时间:使用装饰器来测量函数的执行时间,以便优化代码或提高性能。 例如,以下是一个用于记录函数执行时间的装饰器的例子:
import time
def timeit(f):
def wrapper(*args, **kwargs):
start = time.time()
ret = f(*args, **kwargs)
end = time.time()
print(f"Time taken: {end-start:.6f}")
return ret
return wrapper
@timeit
def calculate_sum(n):
return sum(range(n))
calculate_sum(100000)
运行此代码将会输出类似于 “Time taken: 0.000094” 的值,表示计算 1 到 100000 的和所花费的时间。这个装饰器函数使用了 time 模块来测量函数的执行时间,并打印出时间差。