关于新样式类:Python:总是使用__new__而不是__init__?

Python: always use __new__ instead of __init__?

我知道__init____new__是如何工作的。我想知道有没有什么东西能让__init__做不到?

也就是说,可以用以下模式替换__init__

1
2
3
4
5
class MySubclass(object):
    def __new__(cls, *args, **kwargs):
        self = super(MySubclass, cls).__new__(cls, *args, **kwargs)
        // Do __init__ stuff here
        return self

我在问,因为我想让PythonOO的这个方面更好地适合我的头脑。


所以,一个类的类通常是type,当您调用Class()时,Class类上的__call__()方法处理这个问题。我相信type.__call__()的实施或多或少是这样的:

1
2
3
4
5
6
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):

For example, in the pickle module, __new__ is used to create instances when unserializing objects. In this case, instances are created, but the __init__ method is not invoked.

还有其他类似的答案吗?

我接受这个答案作为我自己的问题的"是"。

I'm wondering if there is anything __init__ can do that __new__ cannot?

是的,与__new__不同,您在__init__方法中执行的操作不会在解压过程中执行。__new__不能作出这种区分。


好吧,在谷歌上找__new__ vs __init__就说明了这一点。

长话短说,__new__返回一个新的对象实例,而__init__不返回任何内容,只初始化类成员。

编辑:要实际回答您的问题,除非您要对不可变类型进行子类化,否则不需要重写__new__