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(一)Python环境安装
Aug 20 Python
Python中使用scapy模拟数据包实现arp攻击、dns放大攻击例子
Oct 23 Python
Python中的列表知识点汇总
Apr 14 Python
解决Shell执行python文件,传参空格引起的问题
Oct 30 Python
selenium+python设置爬虫代理IP的方法
Nov 29 Python
python rsync服务器之间文件夹同步脚本
Aug 29 Python
Python包,__init__.py功能与用法分析
Jan 07 Python
解决pytorch-yolov3 train 报错的问题
Feb 18 Python
用python自动生成日历
Apr 24 Python
opencv读取视频并保存图像的方法
Jun 04 Python
教你用Python+selenium搭建自动化测试环境
Jun 18 Python
python Django框架快速入门教程(后台管理)
Jul 21 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
完美解决phpexcel导出到xls文件出现乱码的问题
2016/10/29 PHP
php实现通过stomp协议连接ActiveMQ操作示例
2020/02/23 PHP
jquery 实现的全选和反选
2009/04/15 Javascript
基于JavaScript实现 获取鼠标点击位置坐标的方法
2013/04/12 Javascript
Highcharts 非常实用的Javascript统计图demo示例
2013/07/03 Javascript
jquery动态加载js三种方法实例
2013/08/03 Javascript
javascript学习笔记(四)function函数部分
2014/09/30 Javascript
深入分析js的冒泡事件
2014/12/05 Javascript
基于JS代码实现当鼠标悬停表格上显示这一格的全部内容
2016/06/12 Javascript
jQuery中fadein与fadeout方法用法示例
2016/09/16 Javascript
AngularJS使用ng-class动态增减class样式的方法示例
2017/05/18 Javascript
基于Vue过渡状态实例讲解
2017/09/14 Javascript
从对象列表中获取一个对象的方法,依据关键字和值
2017/09/20 Javascript
jQuery中ajax请求后台返回json数据并渲染HTML的方法
2018/08/08 jQuery
Python字符串的encode与decode研究心得乱码问题解决方法
2009/03/23 Python
Python+Django在windows下的开发环境配置图解
2009/11/11 Python
Python中的字典遍历备忘
2015/01/17 Python
Python中使用装饰器时需要注意的一些问题
2015/05/11 Python
numpy找出array中的最大值,最小值实例
2018/04/03 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
对python的bytes类型数据split分割切片方法
2018/12/04 Python
python 格式化输出百分号的方法
2019/01/20 Python
python ctypes库2_指定参数类型和返回类型详解
2019/11/19 Python
python实现测试工具(二)——简单的ui测试工具
2020/10/19 Python
使用CSS3来绘制一个月食图案
2015/07/18 HTML / CSS
在Java开发中如何选择使用哪种集合类
2016/08/09 面试题
extern是什么意思
2016/03/10 面试题
文秘自荐信
2013/10/20 职场文书
业务经理岗位职责
2013/11/11 职场文书
大专会计自我鉴定
2014/02/06 职场文书
2014银行领导班子四风对照检查材料思想汇报
2014/09/25 职场文书
自我查摆剖析材料
2014/10/11 职场文书
明星邀请函
2015/02/02 职场文书
2015年专项整治工作总结
2015/04/03 职场文书
2015年企业工作总结范文
2015/04/28 职场文书
三十年再续同学情倡议书
2019/11/27 职场文书