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从ftp下载数据保存实例
Nov 20 Python
跟老齐学Python之编写类之二方法
Oct 11 Python
Django中几种重定向方法
Apr 28 Python
浅析Python的Django框架中的Memcached
Jul 23 Python
python3 unicode列表转换为中文的实例
Oct 26 Python
Python判断两个文件是否相同与两个文本进行相同项筛选的方法
Mar 01 Python
Python 3.8新特征之asyncio REPL
May 28 Python
如何解决cmd运行python提示不是内部命令
Jul 01 Python
python 调用API接口 获取和解析 Json数据
Sep 28 Python
python爬取2021猫眼票房字体加密实例
Feb 19 Python
python线程优先级队列知识点总结
Feb 28 Python
简单介绍Python的第三方库yaml
Jun 18 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高级对象构建 工厂模式的使用
2012/02/05 PHP
PHP实现获取客户端IP并获取IP信息
2015/03/17 PHP
php实现生成code128条形码的方法详解
2017/07/19 PHP
laravel-admin 中列表筛选方法
2019/10/03 PHP
Jquery 动态添加按钮实现代码
2010/05/06 Javascript
写得不错的jquery table鼠标经过变色代码
2013/09/27 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
javascript实现画不相交的圆
2015/04/07 Javascript
JQuery控制radio选中和不选中方法总结
2015/04/15 Javascript
svg动画之动态描边效果
2017/02/22 Javascript
详解写好JS条件语句的5条守则
2019/02/28 Javascript
使用pkg打包ThinkJS项目的方法步骤
2019/12/30 Javascript
angular组件间传值测试的方法详解
2020/05/07 Javascript
Openlayers学习之加载鹰眼控件
2020/09/28 Javascript
原生js实现简单轮播图
2020/10/26 Javascript
React Ant Design树形表格的复杂增删改操作
2020/11/02 Javascript
[00:17]DOTA2荣耀之路5:It’s a disastah!
2018/05/28 DOTA
Python的re模块正则表达式操作
2016/05/25 Python
python实现聚类算法原理
2018/02/12 Python
详解python中asyncio模块
2018/03/03 Python
python交易记录链的实现过程详解
2019/07/03 Python
python实现图像检索的三种(直方图/OpenCV/哈希法)
2019/08/08 Python
初次部署django+gunicorn+nginx的方法步骤
2019/09/11 Python
解决pycharm同一目录下无法import其他文件
2020/02/12 Python
深入理解Tensorflow中的masking和padding
2020/02/24 Python
IE下实现类似CSS3 text-shadow文字阴影的几种方法
2011/05/11 HTML / CSS
荷兰包包购物网站:The Little Green Bag
2018/03/17 全球购物
String s = new String(“xyz”);创建了几个String Object?
2015/08/05 面试题
syb养殖创业计划书
2014/01/09 职场文书
集团薪酬管理制度
2014/01/13 职场文书
测控技术自荐信
2014/06/05 职场文书
2015年前台个人工作总结
2015/04/03 职场文书
小学少先队工作总结2015
2015/05/26 职场文书
休学证明范本
2015/06/19 职场文书
小学数学教学随笔
2015/08/14 职场文书
2019各种保证书范文
2019/06/24 职场文书