2014-12-04 43 views
1

我有一個庫有很多功能。我想要符合基本的方法模式。我希望所有的方法把上下文作爲第一個參數和關鍵字精氨酸,默認爲0使用Python裝飾器來執行標準方法簽名

library_function(context, ..., default=0) 

有沒有一種方法,我可以使用Python裝飾把

bobs_function(foo, bar=None) 

bobs_library_function(context, foo, bar=None, default=0) 

這樣做的目的是提供聲明庫函數的簡寫。而不是每次都明確添加上下文和默認值。

+0

你可以再澄清一下嗎?你的'bobs_function'和'bobs_library_function'的例子是爲了定義函數的例子嗎?或者它們是如何被調用的?如果它是如何被調用的,你期望'context'變量來自哪裏?也就是說,如果你將'bobs_function(foo,bar = None)'作爲一個函數調用,那麼「正確」解決方案應該在哪裏尋找找到作爲第一個參數插入的'context'的東西? – BrenBarn 2014-12-05 02:53:09

+0

我們的目標是能夠創建一個用於聲明測試需要上下文和默認的簡寫。但是你必須明確聲明函數將上下文作爲輸入,或者我必須使用* args,** kwargs作爲參數,但是將* args和** kwargs作爲輸入比手動輸入上下文更麻煩,默認= 0 – 2014-12-05 07:33:00

回答

1

可以使這項工作,如果你只允許你的包裹功能,通過關鍵字參數:

import functools 

def lib(fn): 
    @functools.wraps(fn) 
    def wrapped(context, default=0, **kwargs): 
     print context, default 
     return fn(**kwargs) 
    return wrapped 

@lib 
def bobs_function(foo, bar=None): 
    print foo 
    print bar 


bobs_function('context', foo='foo', bar='bar', default='default') 

打印:

context default 
foo 
bar 
-2

我越是看,想想這更我相信答案是不。

我希望能夠從bobs函數中訪問上下文和默認值。希望我能拿出一個方便的速記,以確保我寫出符合公約的方法簽名。

問題是我必須提前申報bob_function需要的參數。如果它需要一個位置參數,那麼添加一個新的位置參數將會弄亂一切。

所以我的

@library_function 
def bobs_function(foo, bar=None): 
    .... 

首先想到的神奇改變方法簽名將無法正常工作。

我的下一個想法是扭轉它

@library_function(foo, bar=None) 
def bobs_function(*args, **kwargs): 
    ... 

但事實並非甚至語法正確。而我留下的不愉快的結果,不得不從我的參數和費用中撈出我的變數。

因此總結我的問題。如果我想使用上下文,我必須將其傳入。我不能修改bobs_function的實際聲明參數,因此我可以傳遞上下文的唯一方法是使用* args ** kwargs,這比使用更爲不愉快打字

bobs_library_function(context, foo, bar=None, default=0) 

開頭。

+0

不要用答案來更好地解釋你的問題。評論和修改(或刪除您的問題)並評論其他答案以說明什麼是誤解。正如你已經瞭解你自己所需要的是錯誤的定義,但是你沒有在你的問題中提及它:也許在這種情況下,這個問題就會被拒絕並被關閉。 – 2014-12-05 07:41:40

+0

我不想解釋這個問題。我正在試着解釋答案。答案是不。你可以改變傳遞給函數的值,你可以包裝這個函數,你可以用一個新函數完全替換一個函數,但是你不能做的是改變函數的聲明參數。你不能使用上下文或者默認值,除非它們被明確聲明或者以*/**方式聲明,並且在函數寫入器上做了更多的工作。問題在於是否有可能,答案是否定的。 – 2014-12-05 07:55:47

+0

問題的位置在原始函數中提及使用上下文和默認值,而不是在包裝函數中提及? – 2014-12-05 08:00:27