Reputation: 1246
I may be on the wrong path here, so if my approach to this is bogus, please advice.
Basically I have a class that has a dictionary containing printing information for every property. I create a child of this class that adds another property:
class A(object):
_print_dict = {"a": "ms"}
def __init__(self):
self.a = 5
def __str__(self):
s = ""
for attr in self._print_dict:
s += "{} {}\n".format(getattr(self, attr), _print_dict[attr])
return s
class B(A):
def __init__(self):
super(B, self).__init__()
self.b = 10
I could update in B.__init__
, but that would make _print_dict
a instance attribute, right?
class B(A):
def __init__(self):
super(B, self).__init__()
self.b = 10
self._print_dict.update({"b": "V"})
When trying to access _print_dict
outside __init__
however, i get a NameError
:
class B(A):
_print_dict.update({"b": "V"})
def __init__(self):
super(B, self).__init__()
self.b = 10
The same obviously happens with self._print_dict
, since self
is not defined when the class is created (I presume).
Is there a way to alter the class attribute _print_dict
in the subclass B
? Without altering it for class A
as well?
I obviously missed using the parent class's name explicitly:
class B(A):
_print_dict = A._print_dict.copy()
_print_dict.update({"b": "V"})
def __init__(self):
super(B, self).__init__()
self.b = 10
Is this the way to do it? At least it seems to work...
Upvotes: 0
Views: 1881
Reputation: 23144
Updating the dictionary in B.__init__
would not make it an instance attribute. Instead, you would modify the same dictionary each time you make an instance of B
:
>>> class A(object):
... _print_dict = {"a": "ms"}
...
>>> class B(A):
... def __init__(self):
... self._print_dict.update({"b": "V"})
...
>>> A._print_dict is B._print_dict
True # they are the same object
>>> A._print_dict
{'a': 'ms'} # not yet updated
>>> b = B()
>>> A._print_dict is B._print_dict is b._print_dict
True # still the same object
>>> A._print_dict
{'a': 'ms', 'b': 'V'}
If you want to preserve the original dictionary in A
, you have to copy it in the class definition of B
. Dictionaries convieniently have a method for this:
>>> class B(A):
... _print_dict = A._print_dict.copy()
... _print_dict.update({'b': 'V'})
...
>>> A._print_dict is B._print_dict
False # now they are two distinct objects
>>> A._print_dict
{'a': 'ms'}
>>> B._print_dict
{'a': 'ms', 'b': 'V'}
Upvotes: 1