Python 中的函數與類的方法


注:本文轉譯自 Stackoverflow 上 Adding a Method to an Existing Object 的最佳回答。

在 python 中,def 定義的函數與類中的方法有很大的不同,兩者是不同的類型。

>>> def foo():
...     print "foo"
...
>>> class A:
...     def bar( self ):
...         print "bar"
...
>>> a = A()
>>> foo
<function foo at 0x00A98D70>
>>> a.bar
<bound method A.bar of <__main__.A instance at 0x00A9BC88>>
>>>

類中的方法是綁定方法,會具體綁定到某一類的實例。當方法被調用時,實例對象會作為第一個參數(self),被傳入到方法中。

一個類中的可調用屬性一直是未綁定,當類被實例化為一個對象時才綁定到某一具體實例上。所以我們可以在任何時候對類中已定義的方法進行修改。

>>> def fooFighters( self ):
...     print "fooFighters"
...
>>> A.fooFighters = fooFighters
>>> a2 = A()
>>> a2.fooFighters
<bound method A.fooFighters of <__main__.A instance at 0x00A9BEB8>>
>>> a2.fooFighters()
fooFighters

在修改之前已經實例化的對象也會改變(只要它們沒有覆蓋自身屬性)。新添加的方法會自動與實例對象進行綁定。

>>> a.fooFighters()
fooFighters

這種直接添加或修改類中的方法只能在類上進行修改,如果只想給一個實例化的對象增加方法就會產生問題。

>>> def barFighters( self ):
...     print "barFighters"
...
>>> a.barFighters = barFighters
>>> a.barFighters()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: barFighters() takes exactly 1 argument (0 given)

當把方法直接添加到一個實例對象時,函數並沒有自動與與實例對象進行綁定。其仍然是一個函數類型,而不是一個綁定方法 (bound method)。

>>> a.barFighters
<function barFighters at 0x00A98EF0>

我們可以使用 types 模塊中的 MethodType 函數顯示綁定函數到某一個實例對象上。

>>> import types
>>> a.barFighters = types.MethodType( barFighters, a )
>>> a.barFighters
<bound method ?.barFighters of <__main__.A instance at 0x00A9BC88>>
>>> a.barFighters()
barFighters

這樣修改只改變了實例 a 的方法,不會影響到其他實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM