Sudhir Kumar
Sudhir Kumar

Reputation: 81

What is the "Self" object in Python?

I am not understanding the "Self" object in the following Python code:

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

I am not able to understand the result. I was expecting the result for b2.getName( ) to be "Base2" and the result for b2.getB1Name( ) to be "Base1"

Upvotes: 3

Views: 509

Answers (2)

Michael0x2a
Michael0x2a

Reputation: 63998

When you call the super function, you are basically jumping into the constructor of the Ancestor class and executing the code there. In the constructor, you set the name to "Ancestor", overwriting the new name in the base classes.

If you make the call to super the first line in each constructor, it should return the correct name.


However, note that the getB1Name function in B2 will always return the string "Base2" -- the name variable is simply overwritten and isn't "shadowed" in any way.

You could use double-underscore variables, which will automatically do some name-mangling so that the "shadowing" behavior is preserved, but in general, a more cleaner solution would be to simply use different variable names, and design the code so that you don't need two different versions of the same attribute floating around.

Upvotes: 4

BrenBarn
BrenBarn

Reputation: 251353

self refers to the instance, not the class. You have only one instance, so all uses of self refer to the same object. In Base2.__init__ you set a name on this object. You then call super, which invokes Base1.__init__, which sets a new name on the same object, overwriting the old one.

You can use double-underscore attributes to achieve what you want, if you really need to.

Upvotes: 3

Related Questions