2012-08-06 100 views
11

在Python中,假設我有一個函數f,我想傳遞一些輔助參數(爲簡單起見,假設它只是第一個參數保持可變)。functools.partial和類似的lambda之間的區別?

做這兩種方法(如果有的話)之間有什麼區別?

# Assume secondary_args and secondary_kwargs have been defined 

import functools 

g1 = functools.partial(f, *secondary_args, **secondary_kwargs) 
g2 = lambda x: f(x, *secondary_args, **secondary_kwargs) 

doc page for partial,例如,有這樣的話:在類中定義

partial對象的行爲像靜態方法和實例期間不轉換成綁定方法屬性查找。

如果用lambda方法從提供給類的參數(在構造函數中或通過稍後的函數中)創建類方法,是否會受到這種影響?

+1

我認爲我的問題與聯繫的問題完全不同,但是這個問題的最佳答案非常全面,它也回答了我所尋找的許多問題。如果它作爲副本關閉,我不會抱怨。 – ely 2012-08-06 12:43:31

+0

我同意這不是重複的,我已經重新打開你的問題。對於其他參考,相關的問題是[這裏](http://stackoverflow.com/questions/220658/what-is-the-difference-between-a-closure-and-a-lambda)。 – wim 2014-07-30 11:46:39

回答

9
  1. lambda函數與標準函數具有相同的類型,因此它的行爲與實例方法類似。

  2. partial對象在你的例子可以這樣調用:

    g1(x, y, z) 
    

    導致這種呼叫(而不是有效的Python語法,但你的想法):

    f(*secondary_args, x, y, z, **secondary_kwargs) 
    

    拉姆達只接受一個參數並使用不同的參數順序。 (當然,這些差異都可以克服 - 我只是回答你給出的兩個版本之間的區別。)

  3. 執行partial對象比執行等效的lambda稍快。

+0

您是否對'lambda'進行了比較,對「partial」對象進行了分析? – orlp 2012-08-06 12:42:10

+2

@nightcracker:是的,現在不是,但過去幾次。 'partial'對象不會創建一個Python代碼對象,所以它會保存一個完整的Python棧幀。 – 2012-08-06 12:44:32

+0

@Sven Marnach:什麼是更快,創造代碼,調用代碼或兩者? – orlp 2012-08-06 12:46:01

0

我相信類方法只適用於在類定義期間分配的函數。以後分配的功能沒有專門處理。

除此之外,我個人更喜歡lambdas,因爲它們更常見,因此使代碼更易於理解。

class Foo(object): 
    def __init__(self, base): 
     self.int = lambda x:int(x, base) 

print Foo(4).int('11') 
+4

'我個人更喜歡lambdas,因爲它們更常見,因此使代碼更易於理解。「我以前從未聽說過這些語句。 – phant0m 2012-08-06 12:45:23

+0

@ phant0m我聽說過有關Python lambda的大多數聲明在其中都有'broken'這個詞。 ;-) – 2013-11-21 15:44:26

+0

@Chris functools.partial更清潔,但我認爲lambdas更容易理解,只要您沒有確定範圍問題。首先,lambda表達式意味着您不必記住functools.partial所採用的確切參數順序。 – Antimony 2013-11-21 18:11:34

0

是的,lambda會因此而「受苦」。 partial沒有這個問題,因爲它是調用操作符重載的對象,而不是真正的函數。

但是在類定義中使用類似這樣的lambda只是誤用。

0

偏差不僅比已經說過的相當於lambda的速度快20%左右,而且它們保留了與它們相關的直接參考。而在lambdas中,函數在函數體內被「埋入」。

=>如果您只需要解決延遲評估一個函數的問題,直到所有參數已知,然後使用偏分量。與將呼叫埋入匿名函數(即lambda)相比,您將擁有更好的內省方法。