深度解析Python装饰器常见用法与进阶技巧
装饰器的基本原理
装饰器本质上是一个高阶函数,即:以函数为参数并返回新函数的函数。它可以在不修改原始函数代码的前提下,动态地为其添加功能。
def my_decorator(func):
def wrapper(*args, **kwargs):
print('Before function call')
result = func(*args, **kwargs)
print('After function call')
return result
return wrapper
@my_decorator
def say_hello():
print('Hello, world!')
say_hello()
输出:
Before function call
Hello, world!
After function call
函数装饰器的常见用法
1.日志记录
import logging
def log_decorator(func):
def wrapper(*args, **kwargs):
logging.info(f'Calling {func.__name__}')
return func(*args, **kwargs)
return wrapper
2.权限校验
def require_admin(func):
def wrapper(user, *args, **kwargs):
if not user.is_admin:
raise PermissionError('Admin required')
return func(user, *args, **kwargs)
return wrapper
3.性能分析
import time
def timeit(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f'{func.__name__} took {end - start:.4f}s')
return result
return wrapper
4.缓存机制
from functools import lru_cache
@lru_cache(maxsize=128)
def fib(n):
return n if n < 2 else fib(n-1) + fib(n-2)
带参数的装饰器
带参数的装饰器需要再包一层函数:
def repeat(times):
def decorator(func):
def wrapper(*args, **kwargs):
for _ in range(times):
result = func(*args, **kwargs)
return result
return wrapper
return decorator
@repeat(3)
def greet():
print('Hello!')
类装饰器与方法装饰器
类装饰器
可以用于增强类的功能:
def singleton(cls):
instances = {}
def get_instance(*args, **kwargs):
if cls not in instances:
instances[cls] = cls(*args, **kwargs)
return instances[cls]
return get_instance
@singleton
class Database:
pass
方法装饰器
与函数装饰器类似,但要注意 self 的传递:
def method_logger(func):
def wrapper(self, *args, **kwargs):
print(f'Calling {func.__name__} of {self}')
return func(self, *args, **kwargs)
return wrapper
class MyClass:
@method_logger
def foo(self):
print('foo called')
装饰器的嵌套与组合
多个装饰器可以叠加使用,执行顺序为自下而上:
@decorator_a
@decorator_b
def func():
pass
# 等价于 func = decorator_a(decorator_b(func))
进阶技巧:保留元信息与类型提示
装饰器会改变被装饰函数的元信息(如__name__, __doc__),推荐用 functools.wraps 保留原信息:
from functools import wraps
def my_decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
对于类型提示,可以直接在装饰器和被装饰函数中添加 type hints。
装饰器最佳实践
- 始终使用 functools.wraps 保留函数元信息
- 为装饰器编写单元测试,确保功能可复用且无副作用
- 合理使用装饰器,避免过度嵌套导致调试困难
- 利用标准库装饰器(如 @staticmethod, @classmethod, @property, @lru_cache)提升开发效率
- 为装饰器添加类型提示和文档字符串
总结
Python 装饰器让我们以声明式、可复用的方式增强函数和类的行为。掌握装饰器的原理与用法,不仅能提升代码的可读性和复用性,更能让你的 Python 项目更具专业水准。建议在实际开发中多加练习,灵活运用装饰器解决实际问题。
到此这篇关于深度解析Python装饰器常见用法与进阶技巧的文章就介绍到这了,更多相关Python装饰器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
python内置函数breakpoint()与bytearray()示例详解
本文给大家分享的是python内置函数breakpoint()与bytearray()的相关资料,并给大家附上了详细代码,有需要的小伙伴可以参考下2017-04-04
Python用matplotlib库画图中文和负号显示为方框的问题解决
matplotlib中画图的时候会遇到负号显示为方框的问题,下面这篇文章主要给大家介绍了关于Python用matplotlib库画图中文和负号显示为方框的问题解决,文中通过实例代码介绍的非常详细,需要的朋友可以参考下2022-07-07
基于SQLAlchemy实现操作MySQL并执行原生sql语句
这篇文章主要介绍了基于SQLAlchemy实现操作MySQL并执行原生sql语句,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下2020-06-06
Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例
这篇文章主要介绍了Python使用gluon/mxnet模块实现的mnist手写数字识别功能,结合完整实例形式分析了Python调用gluon/mxnet模块识别手写字的具体实现技巧,需要的朋友可以参考下2019-12-12
python sys.stdin和sys.stdout的用法说明
这篇文章主要介绍了python sys.stdin和sys.stdout的用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2021-03-03
pandas实现excel中的数据透视表和Vlookup函数功能代码
今天小编就为大家分享一篇pandas实现excel中的数据透视表和Vlookup函数功能代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2020-02-02


最新评论