綁定和方法調用
現在我們需要再次闡述Python中綁定(binding)的概念,它主要與方法調用相關聯。
方法是類內部定義的函數,這意味著方法是類屬性而不是實例屬性。
其次,方法只有在其所屬的類擁有實例時,才能被調用。當存在一個實例時,方法才被認為是綁定到那個實例了,沒有實例時,方法就是未綁定的。
任何一個方法定義中都有一個參數是變量self。它表示調用此方法的實例對象。
核心筆記:
self變量用于在類實例方法中引用方法所綁定的實例。方法的實例在任何方法調用中總是作為第一參數傳遞的,self代表方法的實例。你必須在方法聲明中放上self,如果你的方法中沒有用到self,那么考慮創建一個常規函數,除非有特殊的原因。畢竟,方法代碼中沒有使用實例,沒有與類關聯其功能,這使它看起來像一個常規函數。
調用綁定方法
一個實例可以調用綁定的方法,調用時,不需要明確地傳入self了,只需要傳入其他參數,這是因為我們遵循了聲明時self必須作為第一參數的一個報酬。
調用非綁定方法
調用非綁定方法并不經常用到。這種方法的主要場景是:你在派生一個子類,而且你要覆蓋父類的方法,這是你需要調用那個父類中想要覆蓋掉的構造方法。
class EmplAddrBookEntry(AddrBookEntry): 'Employee Address Book Entry Class' def __init__ (self, nm, ph, ph) AddrBookEntry.__init__(self, nm, ph) self.empid = id self.email = em
我們重構了子類的構造器,但想盡可能多地重用代碼而不是復制粘貼代碼,所以調用了父類的構造器。
當一個EmplAddrBookEntry被實例化后,調用__init__(),雖然我們沒有AddrBookEntry的實例,但依然可以調用這樣的方法。
這就是調用非綁定方法的最佳地方了。我們在子類構造器中調用父類構造器并且明確地傳遞父類構造器所需要的self參數。子類中__init__()的第一行就是對父類__init__()的調用。我們通過父類名來調用它,一旦調用返回,我們再定義那些僅在子類中使用的定制。
靜態方法和類方法
靜態方法僅是類中的函數(不需要實例),通常的方法需要一個實例(self)作為第一個參數,對于綁定的方法調用來說,self是自動傳遞給這個方法的。而對于類方法而言,需要類而不是實例作為第一個參數,它是由解釋器傳給方法,類不需要特別地命名,類似self,不過很多人使用cls作為變量名字。
staticmethod()和classmethod()內建函數
我們來創建一下靜態方法和類方法:
>>> class TestStaticMethod(object): def foo(): PRint 'calling static method foo()'>>> >>> a = TestStaticMethod()>>> a.foo()Traceback (most recent call last):File "<pyshell#15>", line 1, in <module>a.foo()TypeError: foo() takes no arguments (1 given)
當我們調用這個方法時,解釋器出現錯誤,顯示需要帶self的常規方法聲明。那應該如何做呢?
>>> class TestStaticMethod: def foo(): print 'calling static method foo()' foo = staticmethod(foo)>>> a = TestStaticMethod()>>> a.foo()calling static method foo()>>> TestStaticMethod.foo()calling static method foo()
我們用了staticmethod()內建函數,就能正常通過類或者實例訪問這個方法。
同理,類方法需要這樣定義:
>>> class TestClassMethod(object): def foo(cls): print 'calling class method foo()' print 'foo() is part of class:', cls.__name__ foo = classmethod(foo)>>> TestClassMethod.foo()calling class method foo()foo() is part of class: TestClassMethod>>> b = TestClassMethod()>>> b.foo()calling class method foo()foo() is part of class: TestClassMethod
這里用了cls作為類方法的第一個參數,當然這不是必須的。
使用函數修飾符
看到像foo=staticmethod(foo)這樣的無意義的語法會讓人心煩。它只是臨時的,有待社區對這些語義進行處理。
我們可以把函數修飾符用到這個函數對象上,用它來整理語法。如上面的,我們可以使用這樣寫防止重新賦值:
class TestStaticMethod(object): @staticmethod def foo(): print 'calling static method foo()'class TestClassMethod(object): @classmethod def foo(cls): print 'calling class method foo()' print 'foo() is part of class:', cls.__name__
新聞熱點
疑難解答