-1

I want to create a baseclass that has an attribute which should not change. Any derived class from this baseclass should have this attribute aswell. My idea was:

class baseclass(object):
    flag = "some attr for all classes"
    def __init__(self, baseattr):
        self.baseattr = baseattr


class child(baseclass):
    def __init__(self, baseattr, childattr):
        super(child, self).__init__(baseattr)
        self.childattr = childattr

My thinking was, if I know look at child.__dict__:

print(child.__dict__["flag"])

it should return "special attribute ... baseclass" but instead I get a KeyError:

Traceback (most recent call last):
  File "./test.py", line 14, in <module>
    print(child.__dict__["flag"])
KeyError: 'flag'

while when calling baseclass.__dict__['flag'] everything is fine. Is there a way to set flags for all derived class that inherit from baseclass?

Torilla
  • 383
  • 5
  • 16

1 Answers1

0

First of all, I think it would be nice if you could review the concepts related to a Class definition so you can understand the difference between a class instance and a class object.

Overall, the __dict__ that you're trying to access implements the object namespace. It was not suppose to be accessed directly as you're trying to do. But for the sake of understanding I'll use it to illustrate the class instance vs class object difference.

Calling __dict__ as you were will get you the dict containing the attributes of your child class object (the default ones and the ones you defined in your Class definition):

>>> child.dict

dict_proxy({'module': 'main', 'doc': None, 'init': })

However, when you decided to put flag in your baseclass like you did, you were defining it as a part of your baseclass class object. It is not declared each time for instance, it was declared once you imported your class definition. Therefore, you can see flag if you do:

>>> baseclass.dict

dict_proxy({'module': 'main', 'flag': 'some attr for all classes', 'dict': , 'weakref': , 'doc': None, 'init': })

Finally, if you access an object instance __dict__ you'll see the attributes you declared with self (including baseattr that was declared when you called super):

>>> child('some base attr', 'some child attr').dict

{'childattr': 'some child attr', 'baseattr': 'some base attr'}

That being said, you already have to access to flag from any object instance. Being more specific, you have access to every attribute defined in the class definition, the inherit class definition and in your instance. So I really recommend you stop using __dict__ and access things the way they were intended to:

>>> your_obj_instance = child('some base attr', 'some child attr')

>>> your_obj_instance.childattr

'some child attr'

>>> your_obj_instance.baseattr

'some base attr'

>>> your_obj_instance.flag

'some attr for all classes'

Aurora Wang
  • 1,822
  • 14
  • 22
  • Thank you for your comment. I'm am an autodidact, as I have been "forced" to work with python without ever being educated about it. I am therefor sorry if I've made some arguably avoidable mistakes. The problem is, that I am forced to make decisions on how to treat the class object based on a flag that it has before it ever gets instantiated. – Torilla Dec 11 '18 at 15:51