37,744
社区成员




If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...]), where self is the new instance and the remaining arguments are the same as were passed to __new__().
If __new__() does not return an instance of cls, then the new instance’s __init__() method will not be invoked.
class A(object):
def __init__(self):
print ("__init__")
def __new__(self):
print ("__new__")
A()
$ python test.py
__new__
When subclassing immutable built-in types like numbers and strings, and occasionally in other situations, the static method __new__ comes in handy. __new__ is the first step in instance construction, invoked before __init__. The __new__ method is called with the class as its first argument; its responsibility is to return a new instance of that class. Compare this to __init__: __init__ is called with an instance as its first argument, and it doesn't return anything; its responsibility is to initialize the instance. There are situations where a new instance is created without calling __init__ (for example when the instance is loaded from a pickle). There is no way to create a new instance without calling __new__ (although in some cases you can get away with calling a base class's __new__).
Recall that you create class instances by calling the class. When the class is a new-style class, the following happens when it is called. First, the class's __new__ method is called, passing the class itself as first argument, followed by any (positional as well as keyword) arguments received by the original call. This returns a new instance. Then that instance's __init__ method is called to further initialize it. (This is all controlled by the __call__ method of the metaclass, by the way.)
Here is an example of a subclass that overrides __new__ - this is how you would normally use it.
>>> class inch(float):
... "Convert from inch to meter"
... def __new__(cls, arg=0.0):
... return float.__new__(cls, arg*0.0254)
...
>>> print inch(12)
0.3048
>>>
This class isn't very useful (it's not even the right way to go about unit conversions) but it shows how to extend the constructor of an immutable type. If instead of __new__ we had tried to override __init__, it wouldn't have worked:
>>> class inch(float):
... "THIS DOESN'T WORK!!!"
... def __init__(self, arg=0.0):
... float.__init__(self, arg*0.0254)
...
>>> print inch(12)
12.0
>>>
The version overriding __init__ doesn't work because the float type's __init__ is a no-op: it returns immediately, ignoring its arguments.
All this is done so that immutable types can preserve their immutability while allowing subclassing. If the value of a float object were initialized by its __init__ method, you could change the value of an existing float object! For example, this would work:
>>> # THIS DOESN'T WORK!!!
>>> import math
>>> math.pi.__init__(3.0)
>>> print math.pi
3.0
>>>