why defined '__new__' and '__init__' all in a class

前端 未结 4 793
轻奢々
轻奢々 2020-12-24 03:39

i think you can defined either \'__init__\' or \'__new__\' in a class,but why all defined in django.utils.datastructures.py.

my code:

4条回答
  •  感情败类
    2020-12-24 04:22

    You can define either or both of __new__ and __init__.

    __new__ must return an object -- which can be a new one (typically that task is delegated to type.__new__), an existing one (to implement singletons, "recycle" instances from a pool, and so on), or even one that's not an instance of the class. If __new__ returns an instance of the class (new or existing), __init__ then gets called on it; if __new__ returns an object that's not an instance of the class, then __init__ is not called.

    __init__ is passed a class instance as its first item (in the same state __new__ returned it, i.e., typically "empty") and must alter it as needed to make it ready for use (most often by adding attributes).

    In general it's best to use __init__ for all it can do -- and __new__, if something is left that __init__ can't do, for that "extra something".

    So you'll typically define both if there's something useful you can do in __init__, but not everything you want to happen when the class gets instantiated.

    For example, consider a class that subclasses int but also has a foo slot -- and you want it to be instantiated with an initializer for the int and one for the .foo. As int is immutable, that part has to happen in __new__, so pedantically one could code:

    >>> class x(int):
    ...   def __new__(cls, i, foo):
    ...     self = int.__new__(cls, i)
    ...     return self
    ...   def __init__(self, i, foo):
    ...     self.foo = foo
    ...   __slots__ = 'foo',
    ... 
    >>> a = x(23, 'bah')
    >>> print a
    23
    >>> print a.foo
    bah
    >>> 
    

    In practice, for a case this simple, nobody would mind if you lost the __init__ and just moved the self.foo = foo to __new__. But if initialization is rich and complex enough to be best placed in __init__, this idea is worth keeping in mind.

提交回复
热议问题