Обернутая функция будет доступна как ячейка закрытия функции. Какая ячейка в точности зависит от количества переменных замыкания.
Для простой бандероли, где единственная переменная закрытия является обертывание функция к, это будет первый один:
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
сделать самоанализ только это немного проще.
Я удалил тег 'django'; на самом деле это не характерно для Django. –