Reputation: 890
I have a class that contains class attributes. I need that they are shared as class attributes by a group of other classes, so that if any of them modifies those attributes, they are modified for all of them. I naively tried it using inheritance, but it is not working like that: each class behaves as if it would have their own "copy" of those class attributes.
Files:
# baseClass.py
class BaseClass(object):
iden = 0
# child1.py
from baseClass import BaseClass
class Child1(BaseClass):
@classmethod
def getId(cls):
return cls.iden
# child2.py
from baseClass import BaseClass
class Child2(BaseClass):
@classmethod
def getId(cls):
return cls.iden
The file I am using to test this is:
from child1 import Child1
from child2 import Child2
print(Child1.getId())
Child1.iden = 5
print(Child1.getId())
print(Child2.getId())
The output I am seeing:
0
5
0
How should I do this, so that Child1, Child2 and BaseClass share the iden class attribute?
Upvotes: 0
Views: 153
Reputation: 1172
I would not use inheritance. If you really need to change the attribute from the Child1
and Child2
you can also use __setattr__
and change the attribute of the base class. I would not recommend that though... It seems to me that there is some problem in the design. Why do you need to change the attribute from the children? Maybe you want to add a new class that holds this property and all the other classes will have a reference to it?
As far as I understood, the following should work just fine for your case:
# baseClass.py
class BaseClass(object):
def initializeIden():
# Do some initialization
BaseClass.iden = 0
# child1.py
from baseClass import BaseClass
class Child1:
@classmethod
def getId(self):
if not hasattr(BaseClass, "iden"):
BaseClass.initializeIden()
return BaseClass.iden
# child2.py
from baseClass import BaseClass
class Child2(BaseClass):
@classmethod
def getId(self):
if not hasattr(BaseClass, "iden"):
BaseClass.initializeIden()
return BaseClass.iden
Upvotes: 0
Reputation: 7555
You can do this by adding an iden
property to the metaclass of BaseClass
:
class BaseType(type):
_iden = 0
def _get_iden(cls):
return BaseType._iden
def _set_iden(cls, value):
BaseType._iden = value
iden = property(_get_iden, _set_iden)
class BaseClass(object):
__metaclass__ = BaseType
class Child1(BaseClass):
pass
class Child2(BaseClass):
pass
print Child1.iden
Child1.iden = 5
print Child1.iden
print Child2.iden
Output:
0
5
5
Upvotes: 1
Reputation: 491
Try this:
# baseClass.py
class BaseClass(object):
iden = 0
@classmethod
def set_id(cls, id):
BaseClass.iden = id
You can call it like:
Child1.set_id(5)
Upvotes: 2