carpetemporem
carpetemporem

Reputation: 191

python access to attributes redefined in derived classes

I'm puzzled with python the more I get into it.

For example the following code:

class A:
    def __init__ (self):
        self.test = "a"

    def dump(self):
        print("A.test: %s" % (self.test,))
        print("A.test: %s" % (self.__dict__["test"],))
        print("A.test: %s" % (getattr(self, "test"),))
        print()

class B (A):
    def __init__ (self):
        self.test = "b"

    def dump(self):
        print("B.test: %s" % (self.test,))
        print("B.test: %s" % (self.__dict__["test"],))
        print("B.test: %s" % (getattr(self, "test"),))
        print()


o = B ()
o.dump()
A.dump(o)
super(B, o).dump()

prints:

B.test: b
B.test: b
B.test: b

A.test: b
A.test: b
A.test: b

A.test: b
A.test: b
A.test: b

which seems to show that you can call a function of a base class but if that class has an attribute which was also used in some derived class you can't access this attribute by using the normal object.attribute notation or perhaps you can't access it at all.

Is that really true? If so it would kill - IMHO - the whole python object model.

Upvotes: 0

Views: 333

Answers (3)

thebjorn
thebjorn

Reputation: 27311

Is this what you are looking for?

class A(object):
    def __init__ (self):
        self.__test = "a"

    def dump(self):
        print "A.test:", self.__test

class B (A):
    def __init__ (self):
        super(B, self).__init__()
        self.__test = "b"

    def dump(self):
        print "B.test:", self.__test


o = B()
o.dump()
super(B, o).dump()

output:

B.test: b
A.test: a

(using Python 2, but you get the idea..)

This works because Python does some fancy name-mangling with pseudo-private __variables.

Upvotes: 0

eyquem
eyquem

Reputation: 27575

You say

if that class has an attribute which was also used in some derived class

In the definition of A

class A:
    def __init__ (self):
        self.test = "a"

doesn't mean that an object test of name test is created as an attribute of the class A
It means that each time an object will be instantiated, an attribute test will be creted in THE INSTANCE

So, you can't have hope to access to an attribute of A that doesn't exist.

def A:
    attA = 13

does creates the object 13 as an attribute of A : print(A.attA) will print the value of 13

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599610

o is an instance of B, not A. When it is initialised, it sets the value of its test attribute to "b". At no point do you even call the superclass __init__, so it never gets set to "a" - but even if you did, it can only have one of the values "a" or "b", depending on whether you called super first or second.

No idea why you think this breaks the Python object model.

Upvotes: 6

Related Questions