2011-07-14 42 views
2

我買了這是在下面的代碼說明了裝飾圖書館的一個漂亮怪異的行爲:裝飾Python庫隱藏kwargs內ARGS

from decorator import decorator  

@decorator 
def wrap(f, a, *args, **kwargs): 
    print 'Decorator:', a, args, kwargs 
    return f(a, *args, **kwargs) 

def mywrap(f): 
    def new_f(a, *args, **kwargs): 
     print 'Home made decorator:', a, args, kwargs 
     return f(a, *args, **kwargs) 
    return new_f 

@wrap 
def funcion(a, b, *args, **kwargs): 
    pass 

@mywrap 
def myfuncion(a, b, *args, **kwargs): 
    pass 

funcion(1, b=2) 
myfuncion(1, b=2) 

這個腳本打印的執行:

$ python /tmp/test.py 
Decorator: 1 (2,) {} 
Home made decorator: 1() {'b': 2} 

'裝飾者'隱藏在參數內部的kwargs,我怎麼能解決這個問題,而不使用「自制」裝飾。

謝謝。

回答

5

只因爲你致電b=2功能不會使b一個關鍵字參數; b是原始函數中的位置參數。如果沒有名爲b的參數並且您指定了b=2,b將成爲關鍵字參數。

decorator的行爲其實是最正確的;它生成的包裝與funcion()具有相同的簽名,而由「自制」裝飾器生成的包裝不具有b作爲命名參數。 「自制」包裝「錯誤地」將b置於kwargs中,因爲myfuncion()的簽名表明b不是關鍵字arg,對於調用者來說是隱藏的。

decorator中保留函數簽名是一項功能,而不是bug。