Python: 什么时候总是使用 __new__ 而非 __init__?
我明白__init__
和__new__
是怎么工作的。现在我想知道,__init__
有没有什么是__new__
做不到的呢?
也就是说,是否可以用下面的方式来替代__init__
:
class MySubclass(object):
def __new__(cls, *args, **kwargs):
self = super(MySubclass, cls).__new__(cls, *args, **kwargs)
// Do __init__ stuff here
return self
我问这个问题是因为我想更好地理解Python的面向对象编程。
3 个回答
好吧,我在谷歌上搜索了 __new__ vs __init__
,找到了这个链接。
简单来说,__new__
是用来创建一个新的对象实例的,而 __init__
则什么都不返回,它只是用来初始化类的成员。
补充一下:其实要回答你的问题,除非你在继承一些不可变类型,否则你通常不需要重写 __new__
。
所以,一个类的类型通常是 type
,当你调用 Class()
时,实际上是 Class
的类里的 __call__()
方法在处理这个调用。我觉得 type.__call__()
的实现大概是这样的:
def __call__(cls, *args, **kwargs):
# should do the same thing as type.__call__
obj = cls.__new__(cls, *args, **kwargs)
if isinstance(obj, cls):
obj.__init__(*args, **kwargs)
return obj
直接回答你的问题是,不,__init__()
能做的事情(改变或“初始化”一个特定的实例)只是 __new__()
能做的事情(创建或选择任何它想要的对象,在返回这个对象之前对它做任何事情)的一个子集。
不过,有这两个方法可用是很方便的。使用 __init__()
更简单(它不需要创建任何东西,也不需要返回任何东西),我认为最好是总是使用 __init__()
,除非你有特别的理由去使用 __new__()
。
这是来自guido的帖子的一个可能答案(感谢@fraca7):
举个例子,在pickle模块中,
__new__
用于在反序列化对象时创建实例。在这种情况下,实例被创建了,但__init__
方法并没有被调用。
还有其他类似的答案吗?
我接受这个答案作为对我自己问题的“是”的回答:
我在想,
__init__
能做的事情,有没有是__new__
做不到的?
是的,不像__new__
,你在__init__
方法中写的操作在反序列化过程中不会被执行。__new__
无法区分这一点。