Python:总是使用__new__而不是__init__?

时间:2010-06-28 10:05:48

标签: python new-style-class

我了解__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 OO的这个方面更适合我。

3 个答案:

答案 0 :(得分:22)

因此,类的类通常为type,当您调用Class()时,__call__()类上的Class方法处理该类。我相信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__()的原因。

答案 1 :(得分:4)

guido's post的一个可能的答案(感谢@fraca7):

  

例如,在pickle模块中,__new__用于在反序列化对象时创建实例。在这种情况下,会创建实例,但不会调用__init__方法。

还有其他类似的答案吗?


我接受这个答案是对我自己的问题的'是':

  

我想知道__init__可以做__new__无法做到的事情吗?

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

答案 2 :(得分:2)

好吧,在谷歌上寻找__new__ vs __init__给我看了this

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

编辑:要真正回答你的问题,除非你是不可变类型的子类,否则你永远不需要覆盖__new__