温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

python如何使用类来实现装饰器

发布时间:2022-03-23 10:32:34 来源:亿速云 阅读:478 作者:小新 栏目:web开发

这篇文章主要介绍python如何使用类来实现装饰器,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

尝试用类来实现装饰器

绝大多数装饰器都是基于函数和 闭包 实现的,但这并非制造装饰器的唯一方式。事实上,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.func(*args, **kwargs) def eager_call(self, *args, **kwargs):         print('Call without delay')         return self.func(*args, **kwargs) def delay(duration):     """装饰器:推迟某个函数的执行。同时提供 .eager_call 方法立即执行     """     # 此处为了避免定义额外函数,直接使用 functools.partial 帮助构造     # DelayFunc 实例     return functools.partial(DelayFunc, duration) 如何使用装饰器的样例代码: @delay(duration=2) def add(a, b):     return a + b # 这次调用将会延迟 2 秒 add(1, 2) # 这次调用将会立即执行 add.eager_call(1, 2)

@delay(duration) 就是一个基于类来实现的装饰器。当然,如果你非常熟悉 Python 里的函数和闭包,上面的 delay 装饰器其实也完全可以只用函数来实现。所以,为什么我们要用类来做这件事呢?

与纯函数相比,我觉得使用类实现的装饰器在特定场景下有几个优势:

• 实现有状态的装饰器时,操作类属性比操作闭包内变量更符合直觉、不易出错

• 实现为函数扩充接口的装饰器时,使用类包装函数,比直接为函数对象追加属性更易于维护

• 更容易实现一个同时兼容装饰器与上下文管理器协议的对象

以上是“python如何使用类来实现装饰器”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI