马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
装饰器是 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@my_decoratordef say_hello(): print("Hello!")say_hello()
复制代码 装饰器的工作原理
@符号:@decorator 是装饰器的语法糖,等价于 say_hello = my_decorator(say_hello)。
调用过程:- say_hello 被传递给 my_decorator。my_decorator 返回 wrapper 函数。say_hello 现在指向 wrapper 函数。当调用 say_hello() 时,实际上是调用 wrapper()。
复制代码 带参数的装饰器
偶然候,我们盼望装饰器本身也能继续参数。这可以通过再嵌套一层函数来实现。- def repeat(num_times): def decorator(func): def wrapper(*args, **kwargs): for _ in range(num_times): result = func(*args, **kwargs) return result return wrapper return decorator@repeat(3)def greet(name): print(f"Hello, {name}!")greet("Alice")
复制代码 保存元数据
利用装饰器后,原始函数的元数据(如名称、文档字符串等)会被覆盖。为了保存这些元数据,可以利用 functools.wraps。- import functoolsdef my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print("Something is happening before the function is called.") result = func(*args, **kwargs) print("Something is happening after the function is called.") return result return wrapper@my_decoratordef say_hello(): """Say hello to the user.""" print("Hello!")print(say_hello.__name__) # 输出: say_helloprint(say_hello.__doc__) # 输出: Say hello to the user.
复制代码 类装饰器
除了函数装饰器,Python 还支持类装饰器。类装饰器通常用于修改类的活动。- def add_class_method(cls): def decorator(func): setattr(cls, func.__name__, func) return cls return decorator@add_class_methodclass MyClass: passdef say_hello(self): print("Hello from MyClass!")instance = MyClass()instance.say_hello() # 输出: Hello from MyClass!
复制代码 装饰器组合
可以将多个装饰器应用于同一个函数。装饰器的实行序次是从内到外。- def decorator1(func): def wrapper(): print("Decorator 1") func() return wrapperdef decorator2(func): def wrapper(): print("Decorator 2") func() return wrapper@decorator1@decorator2def say_hello(): print("Hello!")say_hello()# 输出:# Decorator 1# Decorator 2# Hello!
复制代码 带状态的装饰器
偶然候,我们盼望装饰器可以大概记着一些状态信息。这可以通过利用类来实现。- class Counter: def __init__(self, func): self.func = func self.count = 0 def __call__(self, *args, **kwargs): self.count += 1 print(f"Function {self.func.__name__} has been called {self.count} times") return self.func(*args, **kwargs)@Counterdef say_hello(): print("Hello!")say_hello() # 输出: Function say_hello has been called 1 timessay_hello() # 输出: Function say_hello has been called 2 times
复制代码 现实应用
日志 记载- import loggingdef log_function_call(func): def wrapper(*args, **kwargs): logging.info(f"Calling {func.__name__} with args={args} kwargs={kwargs}") result = func(*args, **kwargs) logging.info(f"{func.__name__} returned {result}") return result return wrapper@log_function_calldef add(a, b): return a + badd(3, 5)
复制代码 缓存- from functools import lru_cache@lru_cache(maxsize=128)def fibonacci(n): if n <= 1: return n return fibonacci(n - 1) + fibonacci(n - 2)print(fibonacci(10)) # 输出: 55
复制代码 总结
装饰器是 Python 中一个非常强大的工具,可以用来加强或修改函数和类的活动。通过明白和利用装饰器,你可以编写更加轻便、模块化和可维护的代码。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!qidao123.com:ToB企服之家,中国第一个企服评测及软件市场,开放入驻,技术点评得现金 |