标签:
通过代码验证是最靠谱的:
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)
>>> foo new foo init <class '__main__.Foo'> >>>
查了下官方文档:https://docs.python.org/2.7/reference/datamodel.html#object.__new__
object.__new__(cls[, ...]):
创建一个实例:Called to create a new instance of class cls.
静态方法:__new__() is a static method that takes the class of which an instance was requested as its first argument.
通过调用父辈的__new__:super(currentclass, cls).__new__(cls[, ...])
创建好实例才__init__:If __new__() returns an instance of cls, then the new instance’s __init__() method will be invoked like __init__(self[, ...])
object.__init__(cls[,...]):
有一句话:__new__() to create it, and __init__() to customise it
通过官方文档就能了解__new__()和__init__()的先后顺序了。但是why?
static int
object_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;
}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_init)
{
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 parameters");
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_methods,
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 abstract 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);
}static PyObject *comma = NULL;所以问题得到解决:__new__()的确是创建一个新的实例,__init__()在实例上面进行customize(定制)。
PyObject *abstract_methods = NULL;
PyObject *builtins;
PyObject *sorted;
PyObject *sorted_methods = NULL;
PyObject *joined = NULL;
貌似__new__()是新式类(继承自object)内置有的。
版权声明:本文为博主原创文章,未经博主允许不得转载。
python __new__()和__init__()哪个更早?
标签:
原文地址:http://blog.csdn.net/emaste_r/article/details/47322827