我不理解以下Python代码中的“Self”对象:
>>> class Ancestor( object ):
def __init__( self ):
self.name = "Ancestor"
def getName( self ):
return self.name
>>> class Base1( Ancestor ):
def __init__( self ):
self.name = "Base1"
super( Base1, self ).__init__( )
def getName( self ):
return self.name
>>> class Base2( Base1 ):
def __init__( self ):
self.name = "Base2"
super( Base2, self ).__init__( )
def getName( self ):
return self.name
def getB1Name( self ):
return super( Base2, self ).getName( )
>>> b2 = Base2( )
>>> b2.getName( )
'Ancestor'
>>> b2.getB1Name( )
'Ancestor'
我无法理解结果。我期待b2.getName()的结果为“Base2”,b2.getB1Name()的结果为“Base1”
答案 0 :(得分:4)
当你调用super
函数时,你基本上会跳进Ancestor
类的构造函数并在那里执行代码。在构造函数中,将名称设置为"Ancestor"
,覆盖基类中的新名称。
如果您在每个构造函数中调用super
第一行,它应该返回正确的名称。
但是,请注意getB1Name
中的B2
函数将始终返回字符串"Base2"
- name
变量只是被覆盖并且未被“遮蔽”无论如何。
你可以使用双下划线变量,它会自动进行一些名称修改,以便保留“阴影”行为,但一般来说,更简洁的解决方案就是简单地使用不同的变量名称,并设计代码,以便您不需要浮动相同属性的两个不同版本。
答案 1 :(得分:3)
self
指的是实例,而不是类。您只有一个实例,因此self
的所有用法都指向同一个对象。在Base2.__init__
中,您可以在此对象上设置名称。然后调用super
,调用Base1.__init__
,在同一个对象上设置一个新名称,覆盖旧对象。
如果确实需要,您可以使用double-underscore attributes来达到您想要的效果。