2013-10-29 25 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

谢谢你的建议。 –