访问原始装饰功能以进行测试 [英] Accessing original decorated function for test purposes
问题描述
我在视图函数中使用装饰器( django_annoying
包中的装饰器( @render_to
)。
I'm using a decorator(@render_to
from the django_annoying
package) in a view function.
但是,我想获取由view函数返回的原始dict用于测试目的,而不是 HttpResponse $ c装饰器返回的$ c>对象。
But the thing is that I wanted to get the original dict that is returned by the view function for test purposes, instead of the HttpResponse
object that the decorator returns.
装饰器使用 @wraps
(来自 functools
)。
如果无法访问它,那么您是否知道如何进行测试?
If there is no way to access this, then do you have any idea of how to test this?
推荐答案
包装的函数将作为函数闭包单元提供。
The wrapped function will be available as a function closure cell. Which cell exactly depends on how many closure variables there are.
对于一个简单的包装,其中唯一的闭合变量是要包装的函数,它将是第一个单元格。一个:
For a simple wrapper where the only closure variable is the function-to-wrap, it'll be the first one:
wrapped = decorated.func_closure[0].cell_contents
,但您可能必须检查所有 func_closure
值。
but you may have to inspect all func_closure
values.
Demo using the functools.wraps()
example decorator:
>>> from functools import wraps
>>> def my_decorator(f):
... @wraps(f)
... def wrapper(*args, **kwds):
... print 'Calling decorated function'
... return f(*args, **kwds)
... return wrapper
...
>>> @my_decorator
... def example():
... """Docstring"""
... print 'Called example function'
...
>>> example
<function example at 0x107ddfaa0>
>>> example.func_closure
(<cell at 0x107de3d70: function object at 0x107dc3b18>,)
>>> example.func_closure[0].cell_contents
<function example at 0x107dc3b18>
>>> example()
Calling decorated function
Called example function
>>> example.func_closure[0].cell_contents()
Called example function
查看< @render_to $的a href = https://github.com/skorokithakis/django-annoying/blob/master/annoying/decorators.py#L25 rel = noreferrer>源代码c $ c> 您不必为此担心;
Looking at the source code for @render_to
you don't have to worry about this though; the wrapped function will be stored in the first closure slot, guaranteed.
如果这是Python 3,则可以使用访问包装的函数。 __wrapped __
属性代替:
If this was Python 3 instead, the wrapped function can be accessed with the __wrapped__
attribute instead:
>>> example.__wrapped__
<function example at 0x103329050>
如果可以访问装饰代码本身,则可以在Python 2中轻松添加相同的引用代码也是如此:
And if you had access to the decorator code itself, you can easily add that same reference in Python 2 code too:
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
# implementation
wrapper.__wrapped__ = f
return wrapper
使自省变得容易一些。
这篇关于访问原始装饰功能以进行测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!