I have some objects that have a dictionary of attributes, obj.attrs. The constructor for these objects accepts a dict and/or **kwargs, for convenience.
It looks a little like this:
class Thing:
def __init__(self, attrs={}, **kwargs):
for arg in kwargs:
attrs[arg] = kwargs[arg]
self.attrs = attrs
Such that Thing({'color':'red'}) does the same as Thing(color='red').
My problem is that the constructor somehow remembers the last attrs value passed to it.
For example:
>>> thing1 = Thing(color='red')
>>> thing2 = Thing()
>>> thing2.attrs
{'color': 'red'}
…but thing2.attrs should just be an empty dict! {}
This made me wonder if this isn’t a problem with using both **kwargs and an argument like attrs={}.
Any ideas?
The problem with using default arguments is that only one instance of them actually exists. When you say
attrs={}in your init method definition, that single default {} instance is the default for every call to that method (it doesn’t make a new default empty dict every time, it uses the same one).The problem is that if there’s only one
attrsin existence and then for every instance of Thing you sayself.attrs = attrs, theself.attrsmember variable for every single one of your instance is pointing to the single shared default instance ofattrs.The other question is, isn’t this completely redundant? You can use
**kwargsto pass in keyword/value args or a dictionary. If you just defined this:All of these strategies still work:
So if you simply define and use Thing that way, you’ll avoid your problem altogether.