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使用lxml模块和Requests模块抓取HTML页面的教程
May 16 Python
使用Python对SQLite数据库操作
Apr 06 Python
Python模拟登陆实现代码
Jun 14 Python
Python基于scapy实现修改IP发送请求的方法示例
Jul 08 Python
PyQt5每天必学之QSplitter实现窗口分隔
Apr 19 Python
python文件拆分与重组实例
Dec 10 Python
Python 脚本获取ES 存储容量的实例
Dec 27 Python
python 协程中的迭代器,生成器原理及应用实例详解
Oct 28 Python
wxPython实现列表增删改查功能
Nov 19 Python
python批量处理txt文件的实例代码
Jan 13 Python
python中类与对象之间的关系详解
Dec 16 Python
忆童年!用Python实现愤怒的小鸟游戏
Jun 07 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制作静态网站的模板框架(一)
2006/10/09 PHP
PHP 缓存实现代码及详细注释
2010/05/16 PHP
apache+codeigniter 通过.htcaccess做动态二级域名解析
2012/07/01 PHP
PHP基于GD库实现的生成图片缩略图函数示例
2017/07/05 PHP
PHP 实现页面静态化的几种方法
2017/07/23 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
PHP基于openssl实现非对称加密代码实例
2020/06/19 PHP
jquery中的 $("#jb51")与document.getElementById("jb51") 的区别
2011/07/26 Javascript
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
分享一个自己写的简单的javascript分页组件
2015/02/15 Javascript
JavaScript实现下拉列表框数据增加、删除、上下排序的方法
2015/08/11 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
jQuery表格插件datatables用法汇总
2016/03/29 Javascript
JavaScript仿网易选项卡制作代码
2016/10/06 Javascript
vue动态删除从数据库倒入列表的某一条方法
2018/09/29 Javascript
Vuex的基本概念、项目搭建以及入坑点
2018/11/04 Javascript
javascript关于“时间”的一次探索
2019/07/24 Javascript
layer.open弹层查看缩略图的原图,自适应大小的实例
2019/09/05 Javascript
小程序调用微信支付的方法
2019/09/26 Javascript
JS实现扫码枪扫描二维码功能
2020/01/03 Javascript
微信小程序使用 vant Dialog组件的正确方式
2020/02/21 Javascript
Node.js Domain 模块实例详解
2020/03/18 Javascript
Python实现Kmeans聚类算法
2020/06/10 Python
Ubuntu下升级 python3.7.1流程备忘(推荐)
2018/12/10 Python
Python的形参和实参使用方式
2019/12/24 Python
基于logstash实现日志文件同步elasticsearch
2020/08/06 Python
施华洛世奇新加坡官网:SWAROVSKI新加坡
2020/10/06 全球购物
天游软件面试
2013/11/23 面试题
什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?
2016/08/13 面试题
关于Java finally的面试题
2016/04/27 面试题
读书心得体会
2013/12/28 职场文书
优秀党员获奖感言
2014/02/18 职场文书
2014年仓库保管员工作总结
2014/12/03 职场文书
升职自荐信怎么写
2015/03/05 职场文书
微信小程序结合ThinkPHP5授权登陆后获取手机号
2021/11/23 PHP