Python语言 :装饰器的技巧介绍

本文介绍了Python装饰器的概念及其用途,强调了装饰器在Python中的重要性。通过最佳实践部分,展示了如何使用类实现装饰器,以及使用wrapt模块编写更简洁的装饰器。同时,文中指出了装饰器与装饰器模式的区别,并提醒开发者在编写装饰器时应注意保持函数签名完整,以及在需要修改外部变量时使用nonlocal关键字。
摘要由CSDN通过智能技术生成

装饰器(Decorator) 是 Python 里的一种特殊工具,它为我们提供了一种在函数外部修改函数的灵活能力。它有点像一顶画着独一无二 @ 符号的神奇帽子,只要将它戴在函数头顶上,就能悄无声息的改变函数本身的行为。

你可能已经和装饰器打过不少交道了。在做面向对象编程时,我们就经常会用到 @staticmethod和 @classmethod 两个内置装饰器。此外,如果你接触过 click 模块,就更不会对装饰器感到陌生。click 最为人所称道的参数定义接口 @click.option(...) 就是利用装饰器实现的。

除了用装饰器,我们也经常需要自己写一些装饰器。在这篇文章里,我将从 最佳实践 和 常见错误两个方面,来与你分享有关装饰器的一些小知识。

最佳实践
1. 尝试用类来实现装饰器
绝大多数装饰器都是基于函数和 闭包 实现的,但这并非制造装饰器的唯一方式。事实上,Python 对某个对象是否能通过装饰器( @decorator)形式使用只有一个要求:decorator 必须是一个“可被调用(callable)的对象。

 
# 使用 callable 可以检测某个对象是否“可被调用”

>>> def foo(): pass

...

>>> type(foo)

<class "function">

>>> callable(foo)

True

函数自然是“可被调用”的对象。但除了函数外,我们也可以让任何一个类(class)变得“可被调用”(callable)。办法很简单,只要自定义类的 __call__ 魔法方法即可。

 
class Foo:

def __call__(self):

print("Hello, __call___")

foo = Foo()

# OUTPUT: True

print(callable(foo))

# 调用 foo 实例

# OUTPUT: Hello, __call__

foo()

基于这个特性,我们可以很方便的使用类来实现装饰器。

下面这段代码,会定义一个名为 @delay(duration) 的装饰器,使用它装饰过的函数在每次执行前,都会等待额外的 duration 秒。同时,我们也希望为用户提供无需等待马上执行的 eager_call 接口。

 
import time

import functools

class DelayFunc:

def __init__(self, duration, func):

self.duration = duration

self.func = func

def __call__(self, *args, **kwargs):

print(f"Wait for {self.duration} seconds...")

time.sleep(self.duration)

return self.f

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值