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 相关文章推荐
深入分析在Python模块顶层运行的代码引起的一个Bug
Jul 04 Python
Python操作Oracle数据库的简单方法和封装类实例
May 07 Python
Python 对输入的数字进行排序的方法
Jun 23 Python
Python读取csv文件分隔符设置方法
Jan 14 Python
python石头剪刀布小游戏(三局两胜制)
Jan 20 Python
利用python、tensorflow、opencv、pyqt5实现人脸实时签到系统
Sep 25 Python
python实现控制台输出彩色字体
Apr 05 Python
python 实现仿微信聊天时间格式化显示的代码
Apr 17 Python
通过Python实现一个简单的html页面
May 16 Python
python 如何调用 dubbo 接口
Sep 24 Python
python sleep和wait对比总结
Feb 03 Python
Python IO文件管理的具体使用
Mar 20 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
thinkphp使用literal防止模板标签被解析的方法
2014/11/22 PHP
php实现插入数组但不影响原有顺序的方法
2015/03/27 PHP
PHP基于单例模式实现的数据库操作基类
2016/01/15 PHP
基于yaf框架和uploadify插件,做的一个导入excel文件,查看并保存数据的功能
2017/01/24 PHP
JQuery的$和其它JS发生冲突的快速解决方法
2014/01/24 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
不能不知道的10个angularjs英文学习网站
2016/03/23 Javascript
JCrop+ajaxUpload 图像切割上传的实例代码
2016/07/20 Javascript
如何用js判断dom是否有存在某class的值
2017/02/13 Javascript
原生JS实现九宫格抽奖效果
2017/04/01 Javascript
基于openlayers4实现点的扩散效果
2020/08/17 Javascript
vue2.0 axios跨域并渲染的问题解决方法
2018/03/08 Javascript
JS实现的3des+base64加密解密算法完整示例
2018/05/18 Javascript
vue 2.8.2版本配置刚进入时候的默认页面方法
2018/09/21 Javascript
JavaScript使用闭包模仿块级作用域操作示例
2019/01/21 Javascript
javascript面向对象三大特征之多态实例详解
2019/07/24 Javascript
vue点击按钮动态创建与删除组件功能
2019/12/29 Javascript
Angular8 简单表单验证的实现示例
2020/06/03 Javascript
微信小程序实现拨打电话功能的示例代码
2020/06/28 Javascript
[25:59]Newbee vs TNC 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python实现获取网站PR及百度权重
2015/01/21 Python
在Python的Django框架中用流响应生成CSV文件的教程
2015/05/02 Python
OPENCV去除小连通区域,去除孔洞的实例讲解
2018/06/21 Python
numpy 对矩阵中Nan的处理:采用平均值的方法
2018/10/30 Python
Python实现繁体中文与简体中文相互转换的方法示例
2018/12/18 Python
Django接收照片储存文件的实例代码
2020/03/07 Python
Python简单实现词云图代码及步骤解析
2020/06/04 Python
css3 中的新特性加强记忆详解
2016/04/16 HTML / CSS
FC-Moto美国:欧洲最大的摩托车服装和头盔商店之一
2019/08/24 全球购物
计算s=f(f(-1.4))的值
2014/05/06 面试题
当当网软件测试笔试题
2015/11/24 面试题
研究生毕业鉴定
2014/01/29 职场文书
优秀老员工获奖感言
2014/02/15 职场文书
售房委托书
2014/08/30 职场文书
简单租房协议书
2014/10/21 职场文书
经验交流材料格式
2014/12/30 职场文书