Sometimes you can use __new__ ()
in python to instantiate a particular class from a dict. It may be convenient once in a while. How to create an instance by bypassing the defined __init__ ()
.
It is assumed that the following classes are defined.
class Person(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return "{self.__class__.__name__}({self.name}, {self.age})".format(self=self)
Normally, it is initialized by passing a value as a direct argument as shown below.
p = Person("foo", 20)
print(p)
# Person(foo, 20)
If you want to create an instance from dict, you can write it like this.
d = {"name": "foo", "age": 20}
p = Person.__new__(Person)
p.__dict__.update(d)
print(p)
Person(foo, 20)
Person (** d)
enough?In the case like the previous example, Person (** d)
can also be used to create an instance using dict data. Is this enough?
Sometimes that's not the case. For example, when creating test data, you may want to directly initialize with the calculated value. In a situation where init () is defined with various disturbing calculations in such a class, and you want to bypass the calculation and specify a direct value to initialize the instance.
class X(object):
def __init__(self, d):
self.y = foo(d)
self.z = boo(d)
__new__ ()
is used to create an object when the class is used as a callable object.
__new__ ()
__init __ ()
Also, the instance variable itself of the object is stored in self.__dict__
. Therefore, it is possible to only create an object with __new__ ()
and update __dict__
later.
Of course, note that __init __ ()
is not called.
class X(object):
def __init__(self, d):
self.x = foo(d)
self.y = boo(d)
raise RuntimeError("hmm")
x = X.__new__(X)
x.__dict__.update({"y": 10, "z": 20})
print(x, x.y, x.z)
# <__main__.X object at 0x10f7e4f28> 10 20