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

Eog*_*anM 27 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
Run Code Online (Sandbox Code Playgroud)

我问,因为我想让Python OO的这个方面更适合我.

Mat*_*son 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
Run Code Online (Sandbox Code Playgroud)

你的问题的直接答案是否定的,__init__()可以做的事情(改变/"初始化"指定的实例)是__new__()可以做的事情的一个子集(创建或以其他方式选择它想要的任何对象,对它想要的对象做任何事情)在返回对象之前).

但是,使用这两种方法很方便.使用__init__()更简单(它不需要创建任何东西,它不必返回任何东西),并且我认为__init__()除非您有特定的理由使用,否则最好始终使用__new__().

  • @Ray **你的结论无法从你的前提中得出。**虽然这句话*表面上是正确的,但出于所有明显的原因,不能安全地弃用`__init__()` - 特别是,**(A)**需要保持与现有 Python 生态系统的向后兼容性*和* **(B)** `__new__()` API(其设计要求显式返回实例)与 `__init__()` API 相比的契约脆弱性(其设计没有施加这样的限制)。`__new__()` 会导致 API 违规,这是不好的;`__init__()` 不会*,这很好。 (2认同)

Eog*_*anM 4

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

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

还有其他类似的答案吗?


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

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

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