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 相关文章推荐
详解Django框架中的视图级缓存
Jul 23 Python
最大K个数问题的Python版解法总结
Jun 16 Python
Python文件操作基本流程代码实例
Dec 11 Python
使用Python读取安卓手机的屏幕分辨率方法
Mar 31 Python
Python利用ORM控制MongoDB(MongoEngine)的步骤全纪录
Sep 13 Python
python 变量初始化空列表的例子
Nov 28 Python
python获取依赖包和安装依赖包教程
Feb 13 Python
使用Python 自动生成 Word 文档的教程
Feb 13 Python
Python创建空列表的字典2种方法详解
Feb 13 Python
python之MSE、MAE、RMSE的使用
Feb 24 Python
使用Pyhton 分析酒店针孔摄像头
Mar 04 Python
python跨文件使用全局变量的实现
Nov 17 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程序61条面向对象分析设计的经验小结
2008/11/12 PHP
php Xdebug 调试扩展的安装与使用.
2010/03/13 PHP
在php中判断一个请求是ajax请求还是普通请求的方法
2011/06/28 PHP
PHP 面向对象详解
2012/09/13 PHP
使用dump函数,给php加断点测试
2013/06/25 PHP
php is_writable判断文件是否可写实例代码
2016/10/13 PHP
php变量与数组相互转换的方法(extract与compact)
2016/12/02 PHP
php usort 使用用户自定义的比较函数对二维数组中的值进行排序
2017/05/02 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
2020/03/29 PHP
PHP设计模式(三)建造者模式Builder实例详解【创建型】
2020/05/02 PHP
linux mint下安装phpstorm2020包括JDK部分的教程详解
2020/09/17 PHP
JS操作select下拉框动态变动(创建/删除/获取)
2013/06/02 Javascript
javascript读取Xml文件做一个二级联动菜单示例
2014/03/17 Javascript
通过location.replace禁止浏览器后退防止重复提交
2014/09/04 Javascript
JavaScript中textRange对象使用方法小结
2015/03/24 Javascript
在JavaScript中处理数组之reverse()方法的使用
2015/06/09 Javascript
AngularJs解决跨域问题案例详解(简单方法)
2016/05/19 Javascript
NodeJS实现图片上传代码(Express)
2017/06/30 NodeJs
Three.js实现绘制字体模型示例代码
2017/09/26 Javascript
Vue中之nextTick函数源码分析详解
2017/10/17 Javascript
JS运动特效之链式运动分析
2018/01/24 Javascript
layui添加动态菜单与选项卡 AJAX请求的例子
2019/09/25 Javascript
使用vue cli4.x搭建vue项目的过程详解
2020/05/08 Javascript
Python中shutil模块的学习笔记教程
2017/04/04 Python
Python更新数据库脚本两种方法及对比介绍
2017/07/27 Python
应聘收银员个人的求职信
2013/11/30 职场文书
经贸日语专业个人求职信范文
2013/12/28 职场文书
计算机个人求职信范例
2014/01/24 职场文书
房产转让协议书
2014/04/11 职场文书
2014年班组建设工作总结
2014/12/01 职场文书
2015新员工试用期工作总结
2014/12/12 职场文书
硕士论文致谢范文
2015/05/14 职场文书
胡桃夹子观后感
2015/06/11 职场文书
2015年音乐教学工作总结
2015/07/22 职场文书
Ruby处理YAML和json数据
2022/04/18 Ruby
利用nginx搭建RTMP视频点播、直播、HLS服务器
2022/05/25 Servers