Python装饰器(Decorators)深度解析
·
Python装饰器(Decorators)深度解析
作为一名从后端开发转向Rust的开发者,我发现Python的装饰器与Rust的特质(Traits)有一些相似之处,它们都可以用于扩展代码的功能。今天我想分享一下我对Python装饰器的理解和实践。
什么是装饰器?
装饰器是一种特殊的函数,它可以修改其他函数或类的行为。装饰器的语法使用@符号,放在被装饰函数或类的定义之前。
@decorator
def function():
pass
这相当于:
def function():
pass
function = decorator(function)
装饰器的基本实现
1. 简单装饰器
def simple_decorator(func):
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@simple_decorator
def hello():
print("Hello, world!")
# 调用函数
hello()
输出:
Before function execution
Hello, world!
After function execution
2. 带参数的装饰器
def decorator_with_args(prefix):
def decorator(func):
def wrapper():
print(f"{prefix}: Before function execution")
func()
print(f"{prefix}: After function execution")
return wrapper
return decorator
@decorator_with_args("LOG")
def hello():
print("Hello, world!")
# 调用函数
hello()
输出:
LOG: Before function execution
Hello, world!
LOG: After function execution
3. 保留函数元数据的装饰器
import functools
def decorator_with_metadata(func):
@functools.wraps(func)
def wrapper():
print("Before function execution")
func()
print("After function execution")
return wrapper
@decorator_with_metadata
def hello():
"""Print hello message"""
print("Hello, world!")
# 调用函数
hello()
# 查看函数元数据
print(f"Function name: {hello.__name__}")
print(f"Function docstring: {hello.__doc__}")
输出:
Before function execution
Hello, world!
After function execution
Function name: hello
Function docstring: Print hello message
4. 带参数的函数装饰器
import functools
def decorator_with_args_and_function_args(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("Before function execution")
result = func(*args, **kwargs)
print("After function execution")
return result
return wrapper
@decorator_with_args_and_function_args
def add(a, b):
"""Add two numbers"""
return a + b
# 调用函数
result = add(1, 2)
print(f"Result: {result}")
# 查看函数元数据
print(f"Function name: {add.__name__}")
print(f"Function docstring: {add.__doc__}")
输出:
Before function execution
After function execution
Result: 3
Function name: add
Function docstring: Add two numbers
装饰器的高级用法
1. 类装饰器
class ClassDecorator:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
print("Before function execution")
result = self.func(*args, **kwargs)
print("After function execution")
return result
@ClassDecorator
def hello():
print("Hello, world!")
# 调用函数
hello()
输出:
Before function execution
Hello, world!
After function execution
2. 带参数的类装饰器
class ClassDecoratorWithArgs:
def __init__(self, prefix):
self.prefix = prefix
def __call__(self, func):
def wrapper(*args, **kwargs):
print(f"{self.prefix}: Before function execution")
result = func(*args, **kwargs)
print(f"{self.prefix}: After function execution")
return result
return wrapper
@ClassDecoratorWithArgs("LOG")
def hello():
print("Hello, world!")
# 调用函数
hello()
输出:
LOG: Before function execution
Hello, world!
LOG: After function execution
3. 装饰器链
import functools
def decorator1(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("Decorator 1: Before function execution")
result = func(*args, **kwargs)
print("Decorator 1: After function execution")
return result
return wrapper
def decorator2(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("Decorator 2: Before function execution")
result = func(*args, **kwargs)
print("Decorator 2: After function execution")
return result
return wrapper
@decorator1
@decorator2
def hello():
print("Hello, world!")
# 调用函数
hello()
输出:
Decorator 1: Before function execution
Decorator 2: Before function execution
Hello, world!
Decorator 2: After function execution
Decorator 1: After function execution
4. 装饰器用于类方法
import functools
def method_decorator(func):
@functools.wraps(func)
def wrapper(self, *args, **kwargs):
print("Before method execution")
result = func(self, *args, **kwargs)
print("After method execution")
return result
return wrapper
class MyClass:
@method_decorator
def hello(self):
print("Hello, world!")
# 创建实例并调用方法
obj = MyClass()
obj.hello()
输出:
Before method execution
Hello, world!
After method execution
装饰器的应用场景
1. 日志记录
import functools
import time
def log_execution(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
start_time = time.time()
print(f"Executing {func.__name__}...")
result = func(*args, **kwargs)
end_time = time.time()
print(f"{func.__name__} executed in {end_time - start_time:.4f} seconds")
return result
return wrapper
更多推荐



所有评论(0)