我可以在包装函数之前修补 Python 装饰器吗? [英] Can I patch a Python decorator before it wraps a function?

查看:37
本文介绍了我可以在包装函数之前修补 Python 装饰器吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有装饰器的函数,我正在尝试借助 Python 进行测试 模拟图书馆.我想使用 mock.patch 用一个只调用函数的模拟绕过"装饰器替换真正的装饰器.

I have a function with a decorator that I'm trying test with the help of the Python Mock library. I'd like to use mock.patch to replace the real decorator with a mock 'bypass' decorator which just calls the function.

我想不通的是如何在真正的装饰器包装函数之前应用补丁.我在补丁目标上尝试了一些不同的变体,并重新排序补丁和导入语句,但没有成功.有什么想法吗?

What I can't figure out is how to apply the patch before the real decorator wraps the function. I've tried a few different variations on the patch target and reordering the patch and import statements, but without success. Any ideas?

推荐答案

装饰器在函数定义时应用.对于大多数功能,这是加载模块的时间.(在其他函数中定义的函数在每次调用封闭函数时都会应用装饰器.)

Decorators are applied at function definition time. For most functions, this is when the module is loaded. (Functions that are defined in other functions have the decorator applied each time the enclosing function is called.)

因此,如果您想修补装饰器,您需要做的是:

So if you want to monkey-patch a decorator, what you need to do is:

  1. 导入包含它的模块
  2. 定义模拟装饰器函数
  3. 设置例如 module.decorator = mymockdecorator
  4. 导入使用装饰器的模块,或在您自己的模块中使用它

如果包含装饰器的模块也包含使用它的函数,那么当您看到它们时,这些函数已经被装饰了,您可能是 S.O.L.

If the module that contains the decorator also contains functions that use it, those are already decorated by the time you can see them, and you're probably S.O.L.

编辑以反映自我最初编写此内容以来对 Python 的更改:如果装饰器使用 functools.wraps() 并且 Python 的版本足够新,您也许可以挖掘出原始函数使用 __wrapped__ 属性并重新装饰它,但这绝不能保证,并且您要替换的装饰器也可能不是唯一应用的装饰器.

Edit to reflect changes to Python since I originally wrote this: If the decorator uses functools.wraps() and the version of Python is new enough, you may be able to dig out the original function using the __wrapped__ attribute and re-decorate it, but this is by no means guaranteed, and the decorator you want to replace also may not be the only decorator applied.

这篇关于我可以在包装函数之前修补 Python 装饰器吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆