Python __new__ () and __init__ () which is earlier?

Source: Internet
Author: User

Verification by code is the most reliable:

Class Foo (object):    def __init__ (self):        print ' foo init '    def __new__ (Cls,*args,**kwargs):        print ' foo New '        return object.__new__ (cls,*args,**kwargs)        foo = foo () print type (foo)

Results:


It can be seen that the __new__ () execution order is earlier, in fact, the __new__ () of the new class is the real initialization function.
PS:CLS represents a class, a class that is currently being instantiated, and parameters are provided automatically by the PY interpreter.


The above code can only demonstrate that __new__ is called earlier than __init__. But why?


Checked the Official document: https://docs.python.org/2.7/reference/datamodel.html#object.__new__

object.__new__ (cls[, ...]) :
Create an instance: Called to create a new instance of class CLS.
Static methods: __new__ () is a static method, which takes the class of which an instance were requested as its first argument.
By calling the father's __new__:super (Currentclass, CLS). __new__ (cls[, ...])
Create a good instance before __init__:if __new__ () returns an instance of CLS, then the new instance ' s __init__ () method would be invoked like __i nit__ (self[, ...])

Object.__init__ (cls[,...]):
A Word: __new__ () to create it, and __init__ () to customise it


The sequencing of __new__ () and __init__ () can be understood through official documentation. But why?


Sometimes really hate oneself like to ask the bottom of the root, OK, directly on the source: C:\Python-2.7.9rc1\Objects\typeobject.c:

__init__ () corresponds to the implementation code:
Static Intobject_init (Pyobject *self, Pyobject *args, Pyobject *kwds) {    int err = 0;    if (Excess_args (args, Kwds)) {        Pytypeobject *type = Py_type (self);        if (type->tp_init! = Object_init &&            type->tp_new! = object_new)        {            err = Pyerr_warnex (pyexc_ Deprecationwarning,                       "object.__init__ () takes no Parameters",                       1);        }        else if (type->tp_init! = Object_init | |                 Type->tp_new = = object_new)        {            pyerr_setstring (pyexc_typeerror,                "object.__init__ () takes no Parameters ");            Err =-1;        }    }    return err;}



__new__ () corresponds to the implementation code:
Static Pyobject *object_new (Pytypeobject *type, Pyobject *args, Pyobject *kwds) {int err = 0; if (Excess_args (args, Kwds)) {if (type->tp_new! = object_new && type->tp_init! = object_i NIT) {err = Pyerr_warnex (pyexc_deprecationwarning, "object () takes no parameters"        , 1);                 } else if (type->tp_new! = Object_new | | Type->tp_init = = object_init) {pyerr_setstring (Pyexc_typeerror, "object () takes no PA            Rameters ");        Err =-1;    }} if (Err < 0) return NULL;        if (Type->tp_flags & py_tpflags_is_abstract) {static Pyobject *comma = NULL;        Pyobject *abstract_methods = NULL;        Pyobject *builtins;        Pyobject *sorted;        Pyobject *sorted_methods = NULL;        Pyobject *joined = NULL;        const char *JOINED_STR; /* Compute ",". Join (Sorted (type.__abstractmethods__)) into joined.        */Abstract_methods = Type_abstractmethods (type, NULL);        if (abstract_methods = = NULL) goto error;        Builtins = Pyeval_getbuiltins ();        if (builtins = = NULL) goto error;        sorted = pydict_getitemstring (Builtins, "sorted");        if (sorted = = NULL) goto error; Sorted_methods = Pyobject_callfunctionobjargs (sorted, Abstract_method        s, NULL);        if (sorted_methods = = NULL) goto error;            if (comma = = NULL) {comma = pystring_internfromstring (",");        if (comma = = NULL) goto error;        } joined = Pyobject_callmethod (comma, "join", "O", sorted_methods);        if (joined = = NULL) goto error;        Joined_str = Pystring_asstring (joined); if (joined_str = = NULL) gOTO error; Pyerr_format (Pyexc_typeerror, "Can ' t instantiate abstract class%s" "With Abstrac    T methods%s ", Type->tp_name, JOINED_STR);        Error:py_xdecref (joined);        Py_xdecref (Sorted_methods);        Py_xdecref (Abstract_methods);    return NULL; } return Type->tp_alloc (type, 0);}


We focus on the problem itself, why __new__ earlier than __init__, see Python Source code (C language Implementation):
You can see that object_init () actually does not have any code, just two if judgments, and object_new () is a variety of properties:
static Pyobject *comma = NULL;
Pyobject *abstract_methods = NULL;
Pyobject *builtins;
Pyobject *sorted;
Pyobject *sorted_methods = NULL;
Pyobject *joined = NULL;
So the problem is solved: __new__ () does create a new instance, __init__ () customize (custom) on the instance.


Seemingly __new__ () is a new class (inherited from Object) built-in.


Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.

Python __new__ () and __init__ () which is earlier?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.