2011-08-18 107 views
7

所以我知道在Python中,一切都是'對象',這意味着它可以作爲參數傳遞給方法。但我試圖瞭解這項工作到底如何。所以我嘗試了下面的例子:python方法作爲參數

class A: 

    def __init__(self): 
     self.value = 'a' 

    def my_method(self) 
     print self.value 

class B: 

    def __init__(self): 
     self.values = 'b' 

    def my_method(self, method): 
     method() 

a = A() 
b = B() 
b.my_method(a.my_method) 

現在第一個這是爲了看看事情是如何工作的。我知道我應該例如檢查my_method的參數是否可以調用。現在我的問題是:

這個方法到底在哪裏?我的意思是我收到的輸出是'a',所以我猜測,當一個對象方法作爲參數傳遞,那麼實際的對象呢?在這種情況下,當我通過a.my_method實例a也通過?

+2

如果你使用Python 2,使用'class A(object):'而不是'class A:'來獲得「新風格的類」,這通常更好,你應該使用什麼。 –

回答

8

當訪問a.my_method Python看到,它是類的一個屬性,並且A.my_method有一個方法__get__()所以它調用A.my_method.__get__(a),該方法創建新的對象(即「結合的方法」),其含有兩個至A.my_method參考並提及a本身。當您調用綁定方法時,它會將回調傳遞迴基礎方法。

每次您調用任何方法時都會發生這種情況,不管您是直接調用它,還是像在代碼中一樣,將實際的調用延遲到以後。您可以在http://docs.python.org/reference/datamodel.html#descriptors

+0

感謝您的輸入。 Python可能會很棘手,直到你習慣它:D – Bogdan

4

該方法在這裏傳遞的方式是什麼?

這很容易回答:在Python中,一切都是對象:)也是函數/方法,它們是可作爲參數傳遞的特定函數對象。

在這種情況下,當我通過a.my_method實例a也被傳遞?

是的,在這種情況下,實例a也被傳遞,儘管嵌入在函數對象中並且不能被檢索。相反,你可以傳遞函數本身並提供一個實例。請看下面的例子:

b = B() 
func = A.my_method # Attention, UPPERCASE A 
func(b) 

這將調用A類方法my_methodB一個實例。

+0

嚴格來說,A.my_method既不是函數本身,也是* unbound *方法對象。 a.my_method是一個* bound *方法對象。如果你真的需要(檢查模塊),你可以從a.my_method中檢索一個實例和原始函數,但我沒有看到在這裏做的理由。 –

+0

我試過你的建議,但只有它的工作方式是,如果A.my_method是一個具有obj參數的靜態方法。否則,它期望A. – Bogdan

1

中找到描述符協議的更多描述。函數是Python中的「第一類對象」。這意味着一個函數就像一個列表或一個整數一樣是一個對象。當你定義一個函數時,你實際上是將函數對象綁定到你在def中使用的名字。

函數可以綁定到其他名稱或作爲參數傳遞給函數(或存儲在列表中,或...)。

源:http://mail.python.org/pipermail/tutor/2005-October/042616.html

1

a.my_method返回不完全是你在class A定義(可以通過A.my_method得到它),但函數的對象被稱爲「綁定的方法」,其包含原始功能(或「未結合的方法'在Python 2中,IIRC)和從中檢索它的對象(self參數)。