2013-02-18 8 views
1

Я использую декоратор (@render_to из пакета django_annoying) в виде функции просмотра.Доступ к оригинальной украшенной функции для целей тестирования

Но дело в том, что я хотел получить исходный dict, который возвращается функцией view для целей тестирования, вместо объекта HttpResponse, который возвращает декоратор.

Декоратор использует @wraps (от functools).

Если у вас нет доступа к этому, у вас есть какое-либо представление о том, как проверить это?

+1

Я удалил тег 'django'; на самом деле это не характерно для Django. –

ответ

6

Обернутая функция будет доступна как ячейка закрытия функции. Какая ячейка в точности зависит от количества переменных замыкания.

Для простой бандероли, где единственная переменная закрытия является обертывание функция к, это будет первый один:

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 

сделать самоанализ только это немного проще.

+0

протестирован здесь, и он работает! спасибо за хороший и подробный ответ =) и для информации о python 3. – Arruda