包装后的函数将作为函数闭包单元使用。哪个单元格具体取决于有多少闭包变量。
对于一个简单的包装器,其中唯一的闭包变量是要包装的函数,它将是第一个:
wrapped = decorated.func_closure[0].cell_contents
但您可能必须检查所有 func_closure 值。
使用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
看看source code for @render_to,你不必担心这个;被包装的函数将被存储在第一个闭包槽中,保证。
如果这是 Python 3,则可以使用 __wrapped__ 属性来访问包装函数:
>>> example.__wrapped__
<function example at 0x103329050>
如果您有权访问装饰器代码本身,您也可以轻松地在 Python 2 代码中添加相同的引用:
def my_decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
# implementation
wrapper.__wrapped__ = f
return wrapper
让内省变得简单一点。