2013-02-18 41 views
1

我在查看函數中使用裝飾器(@render_to來自django_annoying程序包)。訪問用於測試目的的原始裝飾函數

但事情是,我想獲得視圖函數返回的原始字典用於測試目的,而不是裝飾器返回的HttpResponse對象。

裝飾者使用@wraps(來自functools)。

如果沒有辦法訪問它,那麼你有沒有關於如何測試的想法?

+1

我刪除了'django'標籤;這不是Django特有的,真的。 – 2013-02-18 18:19:47

回答

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 2013-02-18 19:11:33

相關問題