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实现抓取城市的PM2.5浓度和排名
Mar 19 Python
libreoffice python 操作word及excel文档的方法
Jul 04 Python
Python调用C语言的实现
Jul 26 Python
使用pytorch和torchtext进行文本分类的实例
Jan 08 Python
细数nn.BCELoss与nn.CrossEntropyLoss的区别
Feb 29 Python
pycharm通过anaconda安装pyqt5的教程
Mar 24 Python
Python优秀开源项目Rich源码解析的流程分析
Jul 06 Python
python文件编写好后如何实践
Jul 07 Python
Java Unsafe类实现原理及测试代码
Sep 15 Python
Python实现哲学家就餐问题实例代码
Nov 09 Python
Manjaro、pip、conda更换国内源的方法
Nov 17 Python
解决Tkinter中button按钮未按却主动执行command函数的问题
May 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
Windows和Linux中php代码调试工具Xdebug的安装与配置详解
2014/05/08 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
PHP函数积累总结
2019/03/19 PHP
Yii框架操作cookie与session的方法实例详解
2019/09/04 PHP
如何在标题栏显示框架内页面的标题
2007/02/03 Javascript
javascript removeChild 使用注意事项
2009/04/11 Javascript
JavaScript的parseInt 进制问题
2009/05/07 Javascript
JS+CSS实现一个气泡提示框
2013/08/18 Javascript
jQuery实现div浮动层跟随页面滚动效果
2014/02/11 Javascript
jQuery实现不断闪烁文字的方法
2015/05/15 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
2015/12/10 Javascript
javascript编程开发中取色器及封装$函数用法示例
2017/08/09 Javascript
Angular实现搜索框及价格上下限功能
2018/01/19 Javascript
VUE DOM加载后执行自定义事件的方法
2018/09/07 Javascript
Python实现对百度云的文件上传(实例讲解)
2017/10/21 Python
对python中的logger模块全面讲解
2018/04/28 Python
Python实现从SQL型数据库读写dataframe型数据的方法【基于pandas】
2019/03/18 Python
python实现视频分帧效果
2019/05/31 Python
python 命令行传入参数实现解析
2019/08/30 Python
pip 安装库比较慢的解决方法(国内镜像)
2019/10/06 Python
10行Python代码计算汽车数量的实现方法
2019/10/23 Python
python实现将视频按帧读取到自定义目录
2019/12/10 Python
css3制作动态进度条以及附加jQuery百分比数字显示
2012/12/13 HTML / CSS
新西兰优惠网站:Treat Me
2019/07/04 全球购物
驾驶员培训方案
2014/05/01 职场文书
个人股份转让协议书范本
2014/10/26 职场文书
2014年检验员工作总结
2014/11/19 职场文书
工作检讨书怎么写
2015/01/23 职场文书
2015年纪念“卢沟桥事变”78周年活动方案
2015/05/06 职场文书
公司辞职信模板
2015/05/13 职场文书
2015年酒店服务员工作总结
2015/05/18 职场文书
2016年秋季开学典礼新闻稿
2015/11/25 职场文书
《扇形统计图》教学反思
2016/02/17 职场文书
GTX1660显卡搭配显示器推荐
2022/04/19 数码科技
微信小程序调用python模型
2022/04/21 Python
MySQL事务的隔离级别详情
2022/07/15 MySQL