How can I update an attribute created by a base class' mutable default argument, without modifying that argument?

dictionary, python, super

Solution

`props` should not have a default value like that. Do this instead:

class a(object):
    def __init__(self, props=None):
        if props is None:
            props = {}
        self.props = props

This is a common python "gotcha".

Problem

I've found a strange issue with subclassing and dictionary updates in new-style classes: ``` Python 2.6.2 (r262:71605, Apr 14 2009, 22:40:02) [MSC v.1500 32 bit (Intel)] on win32 >>> class a(object): ... def __init__(self, props={}): ... self.props = props ... >>> class b(a): ... def __init__(self, val = None): ... super(b, self).__init__() ... self.props.update({'arg': val}) ... >>> class c(b): ... def __init__(self, val): ... super(c, self).__init__(val) ... >>> b_inst = b(2) >>> b_inst.props {'arg': 2} >>> c_inst = c(3) >>> c_inst.props {'arg': 3} >>> b_inst.props {'arg': 3} >>> ``` In debug, in second call (`c(3)`) you can see that within `a` constructor `self.props` is already equal to `{'arg': 2}`, and when `b` constructor is called after that, it becomes `{'arg': 3}` for both objects! also, the order of constructors calling is: ``` a, b # for b(2) c, a, b # for c(3) ``` If you replace `self.props.update()` with `self.props = {'arg': val}` in `b` constructor, everything will be OK, and will act as expected But I really need to update this property, not to replace it.

Original source

Related problems