Python装饰器是一种强大的语言特性,它允许程序员在不改变函数代码的情况下,增加或修改函数的行为。装饰器本质上是一个函数,它接受另一个函数作为参数,并返回一个新的函数,通常用于修改函数的行为、添加额外的功能或执行预处理操作。
1. 简单的装饰器示例
让我们从一个简单的装饰器示例开始,理解装饰器的基本概念:
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
def say_hello():
print("Hello!")
say_hello()
执行结果:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
在这个例子中,my_decorator
是一个装饰器函数,它接受一个函数作为参数,并返回一个新的函数 wrapper
。wrapper
函数包裹了原始的 say_hello
函数,在调用 say_hello
前后执行额外的操作。
2. 带参数的装饰器
装饰器可以接受参数,这使得装饰器更加灵活。下面是一个带参数的装饰器示例:
def repeat(num_times):
def decorator_repeat(func):
def wrapper(*args, **kwargs):
for _ in range(num_times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator_repeat
def greet(name):
print(f"Hello {name}")
greet("World")
执行结果:
Hello World
Hello World
Hello World
在这个例子中,repeat
是一个带参数的装饰器工厂函数,它接受一个参数 num_times
,用于指定函数执行的次数。decorator_repeat
函数是真正的装饰器函数,它接受目标函数作为参数,并返回包装函数 wrapper
。
3. 类装饰器
除了函数装饰器外,Python 还支持类装饰器。类装饰器通过实现 __call__
方法来实现装饰器的功能。
class DecoratorClass:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Something is happening before the function is called.")
self.func(*args, **kwargs)
print("Something is happening after the function is called.")
@DecoratorClass
def say_hello():
print("Hello!")
say_hello()
执行结果:
class DecoratorClass:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Something is happening before the function is called.")
self.func(*args, **kwargs)
print("Something is happening after the function is called.")
@DecoratorClass
def say_hello():
print("Hello!")
say_hello()
执行结果:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
在这个例子中,DecoratorClass
是一个类装饰器,它接受目标函数作为参数,并通过 __call__
方法来实现装饰器的功能。
应用案例
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__} executed in {(end_time - start_time):.4f} seconds")
return result
return wrapper
def long_running_function():
time.sleep(2)
print("Function executed.")
long_running_function()
2. 权限检查装饰器
在 Web 应用中,可能需要对某些函数进行权限检查,确保用户有权执行该操作。
def check_permission(func):
def wrapper(user, *args, **kwargs):
if user.is_admin:
return func(user, *args, **kwargs)
else:
raise PermissionError("User does not have permission to execute this function.")
return wrapper
def delete_user(user, user_id):
print(f"User {user_id} deleted successfully.")
class User:
def __init__(self, is_admin):
self.is_admin = is_admin
admin_user = User(is_admin=True)
regular_user = User(is_admin=False)
delete_user(admin_user, user_id=123)
# delete_user(regular_user, user_id=456) # PermissionError: User does not have permission to execute this function.
3. 性能优化装饰器
有时候我们希望对一些函数进行性能优化,缓存其结果以提高效率。
from functools import lru_cache
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(10))
以上是一些简单的 Python 装饰器的示例和应用场景,装饰器是 Python 中非常强大和灵活的特性,能够大大提高代码的可复用性和可维护性。通过深入理解装饰器的原理和应用,可以更好地发挥其威力,写出更加优雅、高效的 Python 代码。