Python如何解除一个装饰器


Posted in Python onAugust 07, 2020

问题

一个装饰器已经作用在一个函数上,你想撤销它,直接访问原始的未包装的那个函数。

解决方案

假设装饰器是通过 @wraps 来实现的,那么你可以通过访问 __wrapped__ 属性来访问原始函数:

>>> @somedecorator
>>> def add(x, y):
...   return x + y
...
>>> orig_add = add.__wrapped__
>>> orig_add(3, 4)
7
>>>

讨论

直接访问未包装的原始函数在调试、内省和其他函数操作时是很有用的。 但是我们这里的方案仅仅适用于在包装器中正确使用了 @wraps 或者直接设置了 __wrapped__ 属性的情况。

如果有多个包装器,那么访问 __wrapped__ 属性的行为是不可预知的,应该避免这样做。 在Python3.3中,它会略过所有的包装层,比如,假如你有如下的代码:

from functools import wraps

def decorator1(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    print('Decorator 1')
    return func(*args, **kwargs)
  return wrapper

def decorator2(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    print('Decorator 2')
    return func(*args, **kwargs)
  return wrapper

@decorator1
@decorator2
def add(x, y):
  return x + y

下面我们在Python3.3下测试:

>>> add(2, 3)
Decorator 1
Decorator 2
5
>>> add.__wrapped__(2, 3)
5
>>>

下面我们在Python3.4下测试:

>>> add(2, 3)
Decorator 1
Decorator 2
5
>>> add.__wrapped__(2, 3)
Decorator 2
5
>>>

最后要说的是,并不是所有的装饰器都使用了 @wraps ,因此这里的方案并不全部适用。 特别的,内置的装饰器 @staticmethod @classmethod 就没有遵循这个约定 (它们把原始函数存储在属性 __func__ 中)。

以上就是Python如何解除一个装饰器的详细内容,更多关于Python 解除装饰器的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
python3编写C/S网络程序实例教程
Aug 25 Python
python搭建服务器实现两个Android客户端间收发消息
Apr 12 Python
matplotlib subplots 调整子图间矩的实例
May 25 Python
解决pyttsx3无法封装的问题
Dec 24 Python
Python+PyQT5的子线程更新UI界面的实例
Jun 14 Python
详解DeBug Python神级工具PySnooper
Jul 03 Python
python实现复制大量文件功能
Aug 31 Python
Pytorch 多维数组运算过程的索引处理方式
Dec 27 Python
logging level级别介绍
Feb 21 Python
Pandas中DataFrame基本函数整理(小结)
Jul 20 Python
python实现每天自动签到领积分的示例代码
Aug 18 Python
python编写扎金花小程序的实例代码
Feb 23 Python
解决Pycharm双击图标启动不了的问题(JetBrains全家桶通用)
Aug 07 #Python
Python实现上下文管理器的方法
Aug 07 #Python
Python 读取位于包中的数据文件
Aug 07 #Python
Python如何绘制日历图和热力图
Aug 07 #Python
Pycharm2020.1安装无法启动问题即设置中文插件的方法
Aug 07 #Python
手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
Aug 07 #Python
Pycharm2020.1安装中文语言插件的详细教程(不需要汉化)
Aug 07 #Python
You might like
深入理解PHP之require/include顺序 推荐
2011/01/02 PHP
Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
2016/08/17 PHP
laravel添加前台跳转成功页面示例
2019/10/22 PHP
Jquery 表单验证类介绍与实例
2013/06/09 Javascript
JS 去前后空格大全(IE9亲测)
2013/07/15 Javascript
JS中typeof与instanceof之间的区别总结
2013/11/14 Javascript
js 赋值包含单引号双引号问题的解决方法
2014/02/26 Javascript
jQuery对象与DOM对象之间的相互转换
2015/03/03 Javascript
jQuery实现的图文高亮滚动切换特效实例
2015/08/10 Javascript
WEB 前端开发中防治重复提交的实现方法
2016/10/26 Javascript
JS限制条件补全问题实例分析
2016/12/16 Javascript
JS原生轮播图的简单实现(推荐)
2017/07/22 Javascript
Vue网页html转换PDF(最低兼容ie10)的思路详解
2017/08/24 Javascript
详解webpack模块化管理和打包工具
2018/04/21 Javascript
js数组去重的方法总结
2019/01/18 Javascript
bootstrap-treeview实现多级树形菜单 后台JSON格式如何组织?
2019/07/26 Javascript
文章或博客自动生成章节目录索引(支持三级)的实现代码
2020/05/10 Javascript
将Django使用的数据库从MySQL迁移到PostgreSQL的教程
2015/04/11 Python
Python创建二维数组实例(关于list的一个小坑)
2017/11/07 Python
Python使用django框架实现多人在线匿名聊天的小程序
2017/11/29 Python
python write无法写入文件的解决方法
2019/01/23 Python
Python3 合并二叉树的实现
2019/09/30 Python
python实现最速下降法
2020/03/24 Python
python3:excel操作之读取数据并返回字典 + 写入的案例
2020/09/01 Python
python读写数据读写csv文件(pandas用法)
2020/12/14 Python
基于PyTorch中view的用法说明
2021/03/03 Python
单位委托书怎么写
2014/08/02 职场文书
高中教师先进事迹材料
2014/08/22 职场文书
区长工作作风个人整改措施
2014/10/01 职场文书
银行贷款收入证明
2014/10/17 职场文书
万里长城导游词
2015/01/30 职场文书
幼儿园辞职书
2015/02/26 职场文书
2015年税务稽查工作总结
2015/05/26 职场文书
企业财务管理制度范本
2015/08/04 职场文书
详解PHP服务器如何在有限的资源里最大提升并发能力
2021/05/25 PHP
MySQL单表千万级数据处理的思路分享
2021/06/05 MySQL