29

我了解两者__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 的这一方面更适合我的脑海。

4

3 回答 3

23

因此,一个类的类通常是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__().

于 2010-06-28T14:59:06.930 回答
4

来自guido 的帖子的一个可能答案(感谢@fraca7):

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

还有其他类似的答案吗?


我接受这个答案作为我自己的问题的“是”:

我想知道是否有什么__init__可以做__new__而不能做的事情?

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

于 2010-06-28T13:50:05.597 回答
2

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

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

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

于 2010-06-28T10:12:15.930 回答