浅析Python装饰器以及装饰器模式
1. 什么是装饰器?
装饰器指的是在代码运行期间动态修改类或函数功能的技术。它是Python中高阶函数的一种应用,让开发者在不修改原有代码的情况下增加功能,提高代码复用性。可以将装饰器看做包裹在原有函数外层的一层函数,它可以修改原函数的行为,也可以返回原函数的调用地址以便后续调用。
在Python中,装饰器以@
符号表示,将装饰器直接放在函数定义的上方。例如下面这个示例:
def my_decorator(func):
def wrapper():
print("Before function is called.")
func()
print("After function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello, world!")
say_hello()
运行结果:
Before function is called.
Hello, world!
After function is called.
my_decorator
就是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数wrapper
,这个函数可以对传入的函数进行包装,加上一些额外的功能。
在上面的例子中,say_hello
函数定义的上方使用了装饰器@my_decorator
,表示say_hello
函数不再是原本的函数,而是my_decorator(say_hello)
得到的新函数。因此,当我们调用say_hello()
时,首先会调用wrapper()
函数,然后才是原本的say_hello()
函数。
2. 装饰器的使用场景
装饰器可以应用在很多场景中,例如记录函数日志、验证用户权限、缓存函数结果等。
2.1 记录函数日志
我们可以编写一个装饰器来记录函数的执行时间和参数:
import time
def log_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"Function {func.__name__} took {(end_time - start_time):.2f} seconds to run.")
return result
return wrapper
@log_time
def my_function():
time.sleep(2)
print("Function is done.")
my_function()
上述代码定义了一个名为log_time
的装饰器,它接受一个函数作为参数,并返回一个新的函数wrapper
。在wrapper
函数内部,首先使用time
模块记录函数的开始时间,然后调用原函数func
,最后再记录函数的结束时间,并计算函数执行的时间差,最后打印出来。最终,返回原函数的结果。
在上述示例中,我们使用装饰器直接将log_time
装饰到my_function
函数定义上方,使得my_function
函数可以记录自己的执行时间。
2.2 验证用户权限
时常我们需要对某些函数或方法进行权限验证,例如某个页面需要用户登录才能查看,我们可以使用装饰器来实现这个功能。
def login_required(func):
def wrapper(*args, **kwargs):
if not check_user_login_status():
return "Please log in first."
else:
return func(*args, **kwargs)
return wrapper
@login_required
def display_user_info(username):
return f"Hello, {username}!"
print(display_user_info("Alice")) # Hello, Alice!
print(display_user_info("")) # Please log in first.
在上述示例中,login_required
装饰器通过调用check_user_login_status()
函数来判断用户是否已经登录,如果已经登录,则继续调用原函数func
,否则返回提示信息。我们只需要将login_required
装饰器应用到需要权限验证的函数定义上方,就能够实现对用户登录状态的验证。
3. 装饰器模式
现在我们已经了解了装饰器的基本用法,假如我们需要对同一函数应用多个装饰器时,该怎么做?这时就需要使用装饰器模式了。
装饰器模式指的是在不改变已有对象接口及其实现的情况下,动态地为对象增加额外的职责。
下面是一个使用装饰器模式计算累加和的例子:
def add_one(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs) + 1
return wrapper
def add_two(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs) + 2
return wrapper
@add_one
@add_two
def calculate_sum(n):
return sum(range(1, n+1))
print(calculate_sum(5)) # 20
在上述示例中,我们定义了两个装饰器add_one
和add_two
,分别对传入的值加1和加2。然后,我们使用了两个装饰器来包装calculate_sum
函数,在调用calculate_sum(5)
时,实际上是在调用add_one(add_two(calculate_sum))(5)
,传入的值先加2,再加1,最后得到答案20。
4. 总结
装饰器是Python中非常有用的高阶函数技术,它可以动态地为函数增加额外的功能,提高代码的复用性。我们可以通过编写装饰器函数来实现对函数的包装,也可以通过应用装饰器来对函数进行动态修改。同时,我们还可以使用装饰器模式来扩展已有对象的功能。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:浅析Python装饰器以及装饰器模式 - Python技术站