3

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"

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Putting the call to super first still won't do what he expects. No matter what order you call the methods in, if you're using self you will only get one value for the attribute. It can be either the lowest or highest in the hierarchy, but you won't get different values depending on which method you call.
Yeah, true. I didn't see the extra methods at first -- I was looking mostly at the constructor.
3

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.

1 Comment

Thanks, that is the explanation that I was looking for

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.