装饰器是 Python 中强大而灵活的功能,用于在不修改函数代码的情况下,增强或修改函数的行为。装饰器通常用于在函数执行前或执行后添加一些额外的功能。
下面是装饰器的基本概念和使用方法:
1. 函数的基本结构:
在理解装饰器之前,先了解一下 Python 函数的基本结构:
def my_function():
# 函数体
return result
2. 装饰器的概念:
装饰器实际上是一个函数,它接受一个函数作为参数,并返回一个新的函数。这个新的函数通常会在调用原始函数之前或之后执行一些额外的操作。
3. 装饰器的基本语法:
def my_decorator(func):
def wrapper():
# 在调用原始函数之前的额外操作
result = func() # 调用原始函数
# 在调用原始函数之后的额外操作
return result
return wrapper
@my_decorator
def my_function():
# 原始函数的实现
return result
在上述例子中,@my_decorator
语法是装饰器的一种简便写法,等同于 my_function = my_decorator(my_function)
。
4. 装饰器的应用:
a. 记录函数执行时间:
import 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__} executed in {end_time - start_time} seconds")
return result
return wrapper
@timing_decorator
def my_function():
# 原始函数的实现
time.sleep(2)
my_function() # 输出: my_function executed in 2.000605821609497 seconds
b. 检查用户权限:
def check_permission_decorator(func):
def wrapper(user):
if user.is_admin:
result = func(user)
return result
else:
raise PermissionError("Insufficient permissions")
return wrapper
@check_permission_decorator
def sensitive_operation(user):
# 原始函数的实现
return "Sensitive operation completed successfully"
# 测试
class User:
def __init__(self, is_admin):
self.is_admin = is_admin
regular_user = User(is_admin=False)
admin_user = User(is_admin=True)
try:
print(sensitive_operation(regular_user)) # 输出: PermissionError
except PermissionError as e:
print(e)
print(sensitive_operation(admin_user)) # 输出: Sensitive operation completed successfully
在上述例子中,check_permission_decorator
装饰器用于检查用户是否有足够的权限执行敏感操作。
5. 内置装饰器:
a. @property
装饰器:
class Circle:
def __init__(self, radius):
self._radius = radius
@property
def radius(self):
return self._radius
@radius.setter
def radius(self, value):
if value < 0:
raise ValueError("Radius cannot be negative")
self._radius = value
# 使用 @property 装饰器,可以像访问属性一样访问方法
circle = Circle(5)
print(circle.radius) # 输出: 5
# 使用 @radius.setter 装饰器,可以像设置属性一样设置方法
circle.radius = 7
print(circle.radius) # 输出: 7
b. @staticmethod
和 @classmethod
装饰器:
class MathOperations:
@staticmethod
def add(x, y):
return x + y
@classmethod
def multiply(cls, x, y):
return x * y
# 使用 @staticmethod 装饰器,方法不依赖于实例
result1 = MathOperations.add(3, 5)
# 使用 @classmethod 装饰器,方法可以访问类的相关信息
result2 = MathOperations.multiply(3, 5)
print(result1) # 输出: 8
print(result2) # 输出: 15
@staticmethod
用于定义静态方法,而 @classmethod
用于定义类方法。静态方法不依赖于实例,而类方法可以访问类的相关信息。
这些例子涵盖了装饰器在实际项目中的常见用法,但装饰器是一个非常灵活的概念,可以根据项目需求进行定制。