Loading... ## Python装饰器底层原理 ### 什么是装饰器 装饰器是Python中的一种特殊函数,主要用于修改或扩展其他函数或方法的功能,而无需修改函数本身的代码。它们通常通过在函数定义前加上@装饰器名称来使用。 ```python @decorator_function def my_function(): pass ``` ### 装饰器的基本结构 一个基本的装饰器包含一个函数,它接受另一个函数作为参数,并返回一个新的函数。这个新的函数通常会在调用时执行一些附加操作,然后调用原始函数。 ```python def simple_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 ``` 使用该装饰器: ```python @simple_decorator def say_hello(): print("Hello!") say_hello() ``` 输出: ``` Something is happening before the function is called. Hello! Something is happening after the function is called. ``` ### 装饰器的底层原理 ![](https://www.8kiz.cn/usr/uploads/2024/07/2200622094.png) 为了理解装饰器的底层原理,我们需要了解以下几个方面: #### 1. 函数是对象 在Python中,函数是第一类对象。这意味着函数可以作为参数传递给另一个函数,可以作为另一个函数的返回值,也可以赋值给变量。 ```python def foo(): print("Hello from foo") bar = foo bar() ``` 输出: ``` Hello from foo ``` #### 2. 闭包 闭包是一种函数,它保留了定义它的环境中的变量。装饰器利用了闭包来包装函数并添加额外的功能。 ```python def outer_func(msg): def inner_func(): print(msg) return inner_func hi_func = outer_func("Hi") hi_func() ``` 输出: ``` Hi ``` #### 3. 高阶函数 装饰器本质上是高阶函数,它们接受函数作为参数,并返回一个新函数。 ```python def decorator_function(original_function): def wrapper_function(): print("Wrapper executed this before {}".format(original_function.__name__)) return original_function() return wrapper_function @decorator_function def display(): print("display function ran") display() ``` 输出: ``` Wrapper executed this before display display function ran ``` ### 常见装饰器模式 #### 无参数装饰器 这是最基本的装饰器模式。它不接受任何参数,只接受一个函数作为参数。 ```python 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 ``` #### 带参数的装饰器 带参数的装饰器可以接受额外的参数。实现这种装饰器时,需要再嵌套一层函数。 ```python def decorator_with_args(arg1, arg2): def decorator(func): def wrapper(*args, **kwargs): print(f"Arguments passed to decorator: {arg1}, {arg2}") return func(*args, **kwargs) return wrapper return decorator @decorator_with_args("Hello", "World") def say_hello(): print("Hello!") say_hello() ``` 输出: ``` Arguments passed to decorator: Hello, World Hello! ``` #### 类装饰器 类装饰器通过实现 `__call__`方法,可以像函数装饰器一样工作。 ```python class ClassDecorator: def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): print("ClassDecorator: Before the function call.") result = self.func(*args, **kwargs) print("ClassDecorator: After the function call.") return result @ClassDecorator def say_hello(name): print(f"Hello, {name}!") say_hello("Alice") ``` 输出: ``` ClassDecorator: Before the function call. Hello, Alice! ClassDecorator: After the function call. ``` ### 装饰器的实际应用 #### 日志记录 装饰器可以用于记录函数调用的日志。 ```python def log_decorator(func): def wrapper(*args, **kwargs): print(f"Function {func.__name__} called with arguments {args} and keyword arguments {kwargs}") return func(*args, **kwargs) return wrapper @log_decorator def add(x, y): return x + y result = add(5, 3) ``` 输出: ``` Function add called with arguments (5, 3) and keyword arguments {} ``` #### 访问控制与权限验证 装饰器可以用于检查用户是否具有执行某些操作的权限。 ```python def require_authentication(func): def wrapper(user, *args, **kwargs): if not user.is_authenticated: print("User is not authenticated.") return return func(user, *args, **kwargs) return wrapper @require_authentication def view_profile(user): print(f"Displaying profile for {user.name}") # 假设User类和user对象已经定义 view_profile(user) ``` #### 缓存 装饰器可以用于缓存函数的结果,提高性能。 ```python def cache(func): cached_results = {} def wrapper(*args): if args in cached_results: return cached_results[args] result = func(*args) cached_results[args] = result return result return wrapper @cache def compute_square(n): return n * n print(compute_square(4)) print(compute_square(4)) # 这次将使用缓存结果 ``` ### 分析说明表 | 装饰器模式 | 说明 | 代码示例 | | ------------ | -------------------------------------- | --------------------------------------------------------------------- | | 无参数装饰器 | 最基本的装饰器模式,不接受额外参数 | ``def decorator(func):``<br>``def wrapper():``<br>`...` | | 带参数装饰器 | 接受额外参数的装饰器,需要嵌套一层函数 | ``def decorator(arg):``<br>``def wrapper(func):``<br>`...` | | 类装饰器 | 通过实现 `__call__`方法来装饰函数 | ``class ClassDecorator:``<br>``def __call__(self, func):``<br>`...` | | 日志记录 | 用于记录函数调用的日志 | ``def log_decorator(func):``<br>`...` | | 权限验证 | 用于检查用户权限 | ``def require_authentication(func):``<br>`...` | | 缓存 | 用于缓存函数结果,提高性能 | ``def cache(func):``<br>`...` | ### 总结 Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。 最后修改:2024 年 07 月 07 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏