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实现计算资源图标crc值的方法
Oct 05 Python
Python XML RPC服务器端和客户端实例
Nov 22 Python
Python 数据处理库 pandas 入门教程基本操作
Apr 19 Python
Python使用requests提交HTTP表单的方法
Dec 26 Python
python的turtle库使用详解
May 10 Python
python内存监控工具memory_profiler和guppy的用法详解
Jul 29 Python
PyQt5使用QTimer实现电子时钟
Jul 29 Python
详解python中的index函数用法
Aug 06 Python
Python图像处理模块ndimage用法实例分析
Sep 05 Python
Python 实现Serial 与STM32J进行串口通讯
Dec 18 Python
用python 绘制茎叶图和复合饼图
Feb 26 Python
python 闭包函数详细介绍
Apr 19 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
实用函数3
2007/11/08 PHP
PHP5.2中date()函数显示时间与北京时间相差8小时的解决办法
2009/05/28 PHP
php设计模式 Composite (组合模式)
2011/06/26 PHP
PHP常用编译参数中文说明
2014/09/27 PHP
php实现RSA加密类实例
2015/03/26 PHP
thinkPHP5项目中实现QQ第三方登录功能
2017/10/20 PHP
PHP实现递归的三种方法
2020/07/04 PHP
js 火狐下取本地路径实现思路
2013/04/02 Javascript
JS window对象的top、parent、opener含义介绍
2013/12/03 Javascript
什么是Node.js?Node.js详细介绍
2014/06/01 Javascript
使用JS+plupload直接批量上传图片到又拍云
2014/12/01 Javascript
JS判断是否360安全浏览器极速内核的方法
2015/01/29 Javascript
利用JavaScript在网页实现八数码启发式A*算法动画效果
2017/04/16 Javascript
vue2.0结合Element实现select动态控制input禁用实例
2017/05/12 Javascript
vue router2.0二级路由的简单使用
2017/07/05 Javascript
详解Vue-Cli 异步加载数据的一些注意点
2017/08/12 Javascript
详解在vue-cli中引用jQuery、bootstrap以及使用sass、less编写css
2017/11/08 jQuery
node Buffer缓存区常见操作示例
2019/05/04 Javascript
nodejs搭建本地服务器并访问文件操作示例
2019/05/11 NodeJs
[46:55]Ti4 冒泡赛第二轮 LGD vs C9
2014/07/14 DOTA
[48:37]EG vs OG 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/18 DOTA
详解appium+python 启动一个app步骤
2017/12/20 Python
Python装饰器模式定义与用法分析
2018/08/06 Python
对Django中的权限和分组管理实例讲解
2019/08/16 Python
pymysql 开启调试模式的实现
2019/09/24 Python
Python实现队列的方法示例小结【数组,链表】
2020/02/22 Python
解决Python图形界面中设置尺寸的问题
2020/03/05 Python
老生常谈CSS中的长度单位
2016/06/27 HTML / CSS
html5使用canvas绘制太阳系效果
2014/12/15 HTML / CSS
简述Html5 IphoneX 适配方法
2018/02/08 HTML / CSS
浅谈html5与APP混合开发遇到的问题总结
2018/03/20 HTML / CSS
安全教育观后感
2015/06/17 职场文书
nginx实现发布静态资源的方法
2021/03/31 Servers
CSS3实现列表无限滚动/轮播效果
2021/06/23 HTML / CSS
PHP中国际化的字符串排序和比较对象详解
2021/08/23 PHP
SpringDataJPA在Entity中常用的注解介绍
2021/12/06 Java/Android