2016-02-10 45 views
6

我注意到,如果我在創建該類的實例時定義了一個等於某個函數的類屬性,則該屬性將成爲一個綁定方法。有人能解釋我這種行爲的原因嗎?Python - 作爲類屬性的函數成爲綁定方法

In [9]: def func(): 
    ...:  pass 
    ...: 

In [10]: class A(object): 
    ....:  f = func 
    ....:  

In [11]: a = A() 

In [12]: a.f 
Out[12]: <bound method A.func of <__main__.A object at 0x104add190>> 

In [13]: a.f() 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-13-19134f1ad9a8> in <module>() 
----> 1 a.f() 
    global a.f = <bound method A.func of <__main__.A object at 0x104add190>> 

TypeError: func() takes no arguments (1 given) 

回答

7

您已將函數賦值給屬性f。因爲函數現在在一個類內成爲一個方法,特別是一個綁定方法(導致它被綁定到對象further explanation here)。

方法在課堂上接受至少一個參數(self),除非它是特意叮囑不要 - 看class methods and static methods - ,出於這個原因,錯誤說func不帶任何參數(因爲它的定義爲def func():),但收到1(self

做你想做什麼,你說你使用的是static method

def func(): 
    pass 

class A(object): 
    f = staticmethod(func) 
應該告訴蟒蛇
1

Python是基於消息OO系統。相反,與JavaScript類似,屬性被解析爲一級函數,然後被調用;正如發現的那樣,這種行爲的機制有點不同。

在Python的要求是,方法具有至少一個參數,通常稱爲self,那將是自動當被調用作爲一種方法提供的關聯的實例。另外(也許就問題來說),Python在建立實例成員綁定時不區分使用def f..f = some_func();可以說這與類之外的行爲相匹配。

在該示例中,將該函數分配給實例'使得它期望被視爲實例方法'。在兩種情況下都是完全相同的 - 無參數 - 函數;只有這樣的未來使用是相關的。

現在,與JavaScript不同,Python通過綁定方法的概念處理方法和對象關聯 - 功能解析爲方法總是「綁定」。

a.f返回綁定方法的行爲 - 將自動爲第一個參數提供綁定對象的函數爲self - 獨立於函數源完成。在這種情況下,這意味着無參數函數在「綁定」時不能使用,因爲它不接受self參數。

g = a.f 
g() 

在這種情況下主叫g()是:

作爲示範,下面將用同樣的方式,因爲源底層方法確實滿足接受實例作爲參數的最低要求失敗相當於撥打func(a)


爲了比較,Java和C#,紅寶石和Smalltalk是基於消息OO系統 - 在這些對象被告知由「名稱」調用方法,代替拆分的方法(或函數)作爲可調用的值。