2010-04-17 41 views
2

我之前讀過一個問題,詢問Python中是否存在times方法,該方法允許函數在連續調用n次。在運行時向函數對象添加方法

大家都建議for _ in range(n): foo()但我想嘗試使用函數裝飾器來編寫不同的解決方案。

這是我有:

def times(self, n, *args, **kwargs): 
    for _ in range(n): 
     self.__call__(*args, **kwargs) 

import new 
def repeatable(func): 
    func.times = new.instancemethod(times, func, func.__class__) 

@repeatable 
def threeArgs(one, two, three): 
    print one, two, three 

threeArgs.times(7, "one", two="rawr", three="foo") 

當我運行程序時,我得到以下異常:

 
Traceback (most recent call last): 
    File "", line 244, in run_nodebug 
    File "C:\py\repeatable.py", line 24, in 
    threeArgs.times(7, "one", two="rawr", three="foo") 
AttributeError: 'NoneType' object has no attribute 'times' 

,所以我想這個裝飾沒有工作?我怎樣才能解決這個問題?

+1

這種方法似乎是不太習慣,少個簡單你正在替換的那個。 – 2010-04-17 23:09:32

回答

3

你的裝飾應該返回函數對象:

def repeatable(func): 
    func.times = new.instancemethod(times, func, func.__class__) 
    return func 

現在,它沒有返回值,所以你實際上是在沒有改變threeArgs

這是因爲這樣的:

@decorator 
def func(...): 
    ... 

更或更少相同:

def func(...): 
    .... 
func = decorator(func) 
+0

真棒,我想我應該想出......哦,謝謝你的幫助 – 2010-04-17 21:30:27

1

您錯過了裝修器末尾的return func聲明。

0

您是否考慮過不將其添加到特定功能,而是允許將其與任何函數一起使用?

def times(n, func, *args, **kwds): 
    return [func(*args, **kwds) for _ in xrange(n)] 

然後(我回來的返回值的列表,但你可以把它寫忽略它們,類似的循環,你有問題。)

在那裏你會,與您的版本,使用:

threeArgs.times(7, "one", two="rawr", three="foo") 

您改用:

times(7, threeArgs, "one", two="rawr", three="foo")