2013-10-29 27 views
1

我無法理解下面的註釋行。 這是一個python程序。[Python]調用方法(self)


class B: 
def bbb(self): 
    method = self.commands[0] 
    method(self) #I can't umderstand this line 

class A(B): 
    def aaa(self): 
     print 'aaa was called' 
    commands = [aaa] 

c = A() 
c.bbb() 

輸出: AAA被稱爲


我覺得上面的方法AAA不帶任何參數。 但要運行此代碼,我需要將「self」傳遞給aaa參數。爲什麼?有沒有文件解釋這個問題?這個問題屬於哪個類別?

任何簡單的代碼都是非常受歡迎的。 因爲我的英語技能太低。 因此也歡迎改善這個問題。

我在閱讀cpython/Lib/distutils/cmd.py:Command.get_sub_commands()時遇到了這個問題。

謝謝您的閱讀。

回答

1

代碼示例的完成方式使得有點難以分辨發生了什麼。然而,這等同於:

child_methods = [] # a list of all the methods in `Child` 

class Parent(object): 
    def parent_method(self): 
     print "parent_method() called" 
     method = child_methods[0] 
     method(self) 

class Child(Parent): 
    def child_method(self): 
     print "child_method() called" 

# add child_method to child_methods 
child_methods.append(Child.child_method) 

正如你所看到的,child_methods[0]實際上是功能Child.child_method,這是一個簡單的功能,而不是一個綁定的方法。它與Child的實例沒有關聯,這就是爲什麼你可以並且必須自己通過self。你會從一個Child實例獲得一個綁定的方法有:

child_obj = Child() 
bound_child_method = child_obj.child_method 

這是由事實Python會查找屬性中的對象的類型,如果他們沒有在該實例中取得不清楚。例如:

# A dummy class to hold attributes 
class Foo(object): 
    pass 

Foo.bar = 123 # we're adding an attribute to the type itself 

foo1 = Foo() 
print foo1.bar # prints 123 
foo1.bar = 456 # this `bar` attribute "hides" the one on the type 
print foo1.bar # prints 456 
foo2 = Foo() 
print foo2.bar # prints the 123 from the type again 

這就是爲什麼你的代碼示例中,commands真的是「全局」變量,它只是被通過的B實例混淆的訪問。 (如果只有B或其子對象訪問此變量,但查找規則是一個小問題,這不一定是壞習慣。)

+0

謝謝。我明白「無約束的方法」需要通過「自我」。 –

+0

準確。如果你添加一個* bound *方法到列表中,使用'child_methods.append(Child()。child_method)',那麼這就沒有必要了 - 它會使用你從它得到的'Child'實例。 – millimoose

+0

這是不一樣的。在問題的代碼中,沒有未綁定的方法訪問。 'method'的值是一個常規函數。 – newacct

2

這條線:

method(self) #I can't umderstand this line 

調用函數aaa()。在你的函數聲明:

def aaa(self): 

aaa確實需要一個參數(self)。這就是爲什麼你必須打電話給method(self)

由於self.commands[0]是一個函數,調用method(self)等於:如果你還有別的要問

aaa(self) 

評論!

+0

謝謝you.It的真實的。我想,如果它的類的方法,勢必method.But這只是我的oppinion的Python自動通過「自我」到第一個參數。 –

+0

是的,它會自動執行此操作。 – aIKid

4

哇,這是令人困惑的寫法。從代碼本身落後的工作:

c = A() 

創建A的看着一個實例:

def aaa(self): 
    print 'aaa was called' 
commands = [aaa] 

這是一個有點混淆的書面;更有意義是這樣的:

def aaa(self): 
    print 'aaa was called' 

commands = [aaa] 

定義的方法aaa,則類變量commands含有aaa作爲元素。現在,看着節目的下一行:

c.bbb() 

由於A沒有bbbA繼承B,我們請教B

class B: 
def bbb(self): 
    method = self.commands[0] 
    method(self) 

既然我們已經確定commands[aaa],第一行意味着method = aaa。所以第二行有效aaa(self)

+0

尼斯和詳細。 – aIKid

+0

謝謝。但爲什麼'aaa(self)'不是'aaa()'。在這段代碼中,'aaa()'不起作用。這是我的問題。 –

+0

調用對象的任何方法隱式地將對象本身作爲第一個參數傳遞。換句話說,你可以把'c.bbb()'看作'B.bbb(c)'。在這種情況下,你可以重寫'aaa'不需要'self'('aaa'不會有參數,而'bbb'需要調用'method()'而不是'method(self)') –

0

通過它更好地使用新的樣式類,A類(對象)的方式:...

所有的Python類的方法有自我作爲第一個參數,除了類方法。 這裏是例如關於自我:

def x(first, arg): 
    print "Called x with arg=",arg 
    print first 

class A(object): 
    some_method = x 

a = A() 
a.some_method("s")` 

http://docs.python.org/2/tutorial/classes.html#random-remarks

+0

謝謝你的建議。 –