Whenever a superclass implements a __init__ method to initialize its attributes, subclasses derived from it have to invoke the __init__ method of the superclass. This recipe is a different mechanism of initializing the attributes of a superclass with default values, achieved by overriding the __new__ method.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
# Simple inheritance case class super1 (object): def __new__(typ, *args, **kwargs): obj = object.__new__(typ, *args, **kwargs) obj.attr1 =  return obj class derived1(super1): def __init__(self, arg4, **kwargs): self.attr4 = arg4 self.attr5 = kwargs['arg5'] if '__main__'==__name__: d1 = derived1(222, arg5=333) d1.attr1.append(111) print d1.attr1, d1.attr4, d1.attr5, print isinstance(d1, super1) # Multiple inheritance case class super2 (object): def __new__(typ, *args, **kwargs): obj = object.__new__(typ, *args, **kwargs) obj.attr2 = 222 return obj import copy class derived2 (super1, super2): def __new__(typ, *args, **kwargs): objList = [sup.__new__(typ, *args, **kwargs) for sup in derived2.__bases__] for obj in objList[1:]: objList.__dict__.update(copy.deepcopy(obj.__dict__)) objList.attr3 = 333 return objList def __init__(self, arg4, **kwargs): self.attr1.append(111) self.attr4 = arg4 self.attr5 = kwargs['arg5'] if '__main__'==__name__: d1 = derived2(444, arg5=555) print d1.attr1, d1.attr2, d1.attr3, d1.attr4, d1.attr5, print isinstance(d1, super1), print isinstance(d1, super2)
The code shows how to override the __new__ method in order to initialize instance attributes with default values. This may be desirable to ensure that attributes are initialized correctly in subclasses regardless of how the __init__ methods of those subclasses are implemented (e.g., it ensures that the superclasss attributes are initialized before the subclasss attributes). Overriding the __new__ method can be useful also in other cases. This recipe can be seen as a more general mechanism to follow whenever overriding the __new__ method.
Class super1 overrides its __new__ method in order to initialize its attributes with default values. This allows its subclass derived1 to define its own method __init__ without invoking a parent classs __init__ method.
Class super2 is implemented in a similar way, but class derived2 shows how to use such a mechanism in the case of multiple inheritance. Attributes from the superclasses are inherited in this example from left to right, which means that attributes in a superclass can be overridden by attributes in a superclass that succeeds the first one in the inheritance sequence of class derived2. Other implementations can use a different inheritance order by changing the order in the list objList.
One object is created for each superclass, but one of them is chosen to update its own dictionary __dict__ with the entries from all the other objects. Finally, this object is the new object that is returned by the __new__ method.