Python 中的函數與類的方法

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

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

>>> 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),被傳入到方法中。函數

一個類中的可調用屬性一直是未綁定,當類被實例化爲一個對象時才綁定到某一具體實例上。因此咱們能夠在任什麼時候候對類中已定義的方法進行修改。code

>>> 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

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

>>> 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)。get

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

咱們能夠使用 types 模塊中的 MethodType 函數顯示綁定函數到某一個實例對象上。io

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

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

相關文章
相關標籤/搜索