Python 装饰器使用
一、装饰器是什么?
装饰器是 Python 中一种用于修改或扩展函数行为的机制。它们允许你在不修改原始函数代码的情况下,通过包装原始函数来添加额外的功能。装饰器的主要目的是提高代码的可重用性和可维护性,并在不同的函数之间共享通用的功能。
装饰器的作用包括:
- 代码复用: 装饰器允许将通用功能从函数中分离出来,以便在不同的函数间共享。这样可以减少代码重复,提高代码的可维护性。
- 功能扩展: 装饰器允许在不修改原始函数代码的情况下,为函数添加额外的功能。这使得可以轻松地扩展函数的行为,例如添加日志记录、性能测量、缓存等。
- 代码清晰: 装饰器提供了一种清晰且可读的方式来添加和管理函数的功能。通过将装饰器应用于函数,可以使代码更加模块化和易于理解。
二、装饰器的简单使用案例
def greeting():
print("Hello, welcome to the world of decorators!")
# 定义装饰器函数
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
# 使用装饰器
greeting = my_decorator(greeting)
# 调用经过装饰的函数
greeting()
在这个例子中,my_decorator
是一个装饰器函数。当我们调用 my_decorator(greeting)
时,它实际上返回了一个新的函数 wrapper
,这个函数在调用 greeting
函数前后分别输出了额外的信息。
通过这种方式,我们实现了对 greeting
函数的功能扩展,而不需要修改原始的 greeting
函数定义。这使得我们可以通过装饰器轻松地添加、修改或组合函数的功能,而无需更改它们的实际实现。
上面的代码可以使用装饰器语法更简洁地写成:
@my_decorator
def greeting():
print("Hello, welcome to the world of decorators!")
# 调用经过装饰的函数
greeting()
使用 @my_decorator
语法是将 greeting
函数传递给 my_decorator
装饰器的一种简洁方式。这相当于使用 my_decorator(greeting)
来包装 greeting
函数,使其在调用时受到装饰器定义的影响。【意思是把greeting函数放入my_decorator装饰器中,就是一个形参】
三、应用场景
3.1 日志记录
装饰器可用于自动记录函数的调用信息,例如函数名称、参数和执行时间,从而实现简单而强大的日志记录。
pythonCopy codedef log_decorator(func):
def wrapper(*args, **kwargs):
print(f"Calling {func.__name__} with args {args} and kwargs {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} returned {result}")
return result
return wrapper
@log_decorator
def add(a, b):
return a + b
add(2, 3)
3.2 性能测量
装饰器可以用于测量函数的执行时间,从而帮助识别性能瓶颈或优化代码。
pythonCopy codeimport time
def timing_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} took {end_time - start_time} seconds to execute.")
return result
return wrapper
@timing_decorator
def slow_function():
time.sleep(2)
print("Function executed.")
slow_function()
3.3 缓存
装饰器可以用于实现缓存,将函数的计算结果缓存起来,以避免重复计算。
pythonCopy codedef memoize(func):
cache = {}
def wrapper(*args):
if args not in cache:
result = func(*args)
cache[args] = result
return cache[args]
return wrapper
@memoize
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)
print(factorial(5)) # 只计算一次,后续调用直接使用缓存结果
3.4 权限验证
装饰器可以用于检查用户权限或身份验证,以确保只有授权用户可以访问某些功能。
pythonCopy codedef authenticate(func):
def wrapper(user, *args, **kwargs):
if user.is_authenticated:
return func(user, *args, **kwargs)
else:
raise PermissionError("User is not authenticated.")
return wrapper
@authenticate
def protected_resource(user):
print(f"{user.username} is accessing the protected resource.")
# 如果用户经过身份验证,则可以访问受保护的资源
protected_resource(authenticated_user)
这些只是装饰器的一些常见应用场景,实际上,它们非常灵活,可以根据需要创建适用于各种用例的装饰器。通过使用装饰器,可以将通用的功能模块化,并将其应用于多个函数,从而提高代码的可维护性和可读性。
装饰器提供的主要优势之一是它可以将通用的功能从业务逻辑中分离出来,提高了代码的可维护性和可读性