我即将提出的问题似乎是Python使用__new__和__init__的重复?,但无论如何,我仍然不清楚__new__
和__init__
之间的实际区别是什么。
在你急于告诉我__new__
用于创建对象,__init__
用于初始化对象之前,让我明确一点:我明白了。事实上,这种区别对我来说是很自然的,因为我有C++的经验,我们有放置new,它类似地将对象分配与初始化分开。
Python C API教程这样解释:
新会员负责 创建(与初始化相反) 类型的对象。 它暴露在 Python作为
__new__()
方法。 ... 实现新方法的一个原因是确保 实例变量。
所以,是的-Igetwhat__new__
does,但是尽管如此,我仍然不明白为什么它在Python中有用。 给出的例子说,如果你想"保证实例变量的初始值",__new__
可能是有用的。 那么,这不正是__init__
将要做的吗?
在C API教程中,显示了一个示例,其中创建了一个新类型(称为"Noddy"),并定义了该类型的__new__
函数。 Noddy类型包含一个名为first
的字符串成员,这个字符串成员被初始化为一个空字符串,如下所示:
static PyObject * Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
.....
self->first = PyString_FromString("");
if (self->first == NULL)
{
Py_DECREF(self);
return NULL;
}
.....
}
请注意,如果没有这里定义的__new__
方法,我们将不得不使用PyType_GenericNew
,它简单地将所有实例变量成员初始化为NULL。 因此,__new__
方法的唯一好处是实例变量将以空字符串开始,而不是NULL。 但是为什么这是有用的,因为如果我们关心确保我们的实例变量初始化为一些默认值,我们可以在__init__
方法中这样做?
__new__
可能还有其他用途,但有一个非常明显的用途:你不能在不使用__new__
的情况下对不可变类型进行子类化。 例如,假设你想创建一个元组的子类,它只能包含0到size
之间的整数值。你根本不能用
__init__
做到这一点-如果你试图修改__init__
中的__init__
,解释器会抱怨你试图修改一个不可变对象。