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 相关文章推荐
多线程爬虫批量下载pcgame图片url 保存为xml的实现代码
Jan 17 Python
python实现数通设备端口监控示例
Apr 02 Python
Python MySQL数据库连接池组件pymysqlpool详解
Jul 07 Python
Python IDLE入门简介
Dec 08 Python
PyQt5 pyqt多线程操作入门
May 05 Python
详解python函数的闭包问题(内部函数与外部函数详述)
May 17 Python
Python定时任务工具之APScheduler使用方式
Jul 24 Python
python图片二值化提高识别率代码实例
Aug 24 Python
python词云库wordcloud的使用方法与实例详解
Feb 17 Python
在python中使用nohup命令说明
Apr 16 Python
Python基于locals返回作用域字典
Oct 17 Python
pd.drop_duplicates删除重复行的方法实现
Jun 16 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
Zend Framework教程之Zend_Config_Ini用法分析
2016/03/23 PHP
PHP编程实现计算抽奖概率算法完整实例
2017/08/09 PHP
laravel 解决路由除了根目录其他都404的问题
2019/10/18 PHP
javascript 简单高效判断数据类型 系列函数 By shawl.qiu
2007/03/06 Javascript
javascript concat数组累加 示例
2009/09/03 Javascript
基于jquery的图片懒加载js
2010/06/30 Javascript
jQuery的初始化与对象构建之浅析
2011/04/12 Javascript
JQuery中SetTimeOut传参问题探讨
2013/05/10 Javascript
在js文件中如何获取basePath处理js路径问题
2013/07/10 Javascript
jQuery中校验时间格式的正则表达式小结
2013/09/22 Javascript
jQuery对Select的操作大集合(收藏)
2013/12/28 Javascript
Jquery获取和修改img的src值的方法
2014/02/17 Javascript
JavaScript通过this变量快速找出用户选中radio按钮的方法
2015/03/23 Javascript
JS获得图片alt信息的方法
2015/04/01 Javascript
js实现统计字符串中特定字符出现个数的方法
2016/08/02 Javascript
浅谈JS之tagNaem和nodeName
2016/09/13 Javascript
详解jQuery中关于Ajax的几个常用的函数
2017/07/17 jQuery
jQuery读取本地的json文件(实例讲解)
2017/10/31 jQuery
Webpack 之 babel-loader文件预处理器详解
2018/03/23 Javascript
ES6 Object方法扩展的应用实例分析
2019/06/25 Javascript
vue改变循环遍历后的数据实例
2019/11/07 Javascript
react使用CSS实现react动画功能示例
2020/05/18 Javascript
pygame学习笔记(4):声音控制
2015/04/15 Python
Python虚拟环境项目实例
2017/11/20 Python
基于python历史天气采集的分析
2019/02/14 Python
Python子类继承父类构造函数详解
2019/02/19 Python
利用Python半自动化生成Nessus报告的方法
2019/03/19 Python
利用python实现短信和电话提醒功能的例子
2019/08/08 Python
Python 字符串处理特殊空格\xc2\xa0\t\n Non-breaking space
2020/02/23 Python
Python使用pyyaml模块处理yaml数据
2020/04/14 Python
StubHub哥伦比亚:购买和出售您的门票
2016/10/20 全球购物
C/C++程序员常见面试题二
2015/11/19 面试题
新大陆软件面试题
2016/11/24 面试题
科研先进个人典型材料
2014/01/31 职场文书
2015年党员个人剖析材料
2014/12/18 职场文书
ORM模型框架操作mysql数据库的方法
2021/07/25 MySQL