【发布时间】:2016-05-28 21:21:56
【问题描述】:
在 Python 中,__new__ 用于初始化不可变类型,__init__ 通常用于初始化可变类型。如果从语言中删除__init__,什么不能再(轻松地)完成?
例如,
class A:
def __init__(self, *, x, **kwargs):
super().__init__(**kwargs)
self.x = x
class B(A):
def __init__(self, y=2, **kwargs):
super().__init__(**kwargs)
self.y = y
可以像这样使用__new__ 重写:
class A_N:
def __new__(cls, *, x, **kwargs):
obj = super().__new__(cls, **kwargs)
obj.x = x
return obj
class B_N(A_N):
def __new__(cls, y=2, **kwargs):
obj = super().__new__(cls, **kwargs)
obj.y = y
return obj
澄清问题范围:这不是关于如何使用__init__ 和__new__ 或它们之间有什么区别的问题。这是一个关于如果从语言中删除__init__ 会发生什么的问题。有什么会坏吗?有什么事情会变得更难或不可能吗?
【问题讨论】:
-
@matino were 是虚拟语气; was 是指示性的。
-
@MokonaModoki 这不是重复的。你看我的说明了吗?
-
@PM2Ring: "
__new__是构造函数,__init__是初始化函数" - 为什么人们一直这么说?在什么奇怪的定义中,__init__不是构造函数?它接受一个已分配的、未初始化的对象并将其带入一个已初始化的、可用的状态。这就是构造函数在几乎所有具有构造函数的语言中所做的事情。我不知道构造函数负责分配的任何定义,例如__new__。 Python 在__new__中有它奇怪的分配器/辅助构造器的东西,因为事实证明第一个构造器设计不够灵活。 -
@user2357112:我猜人们一直在说,因为
__new__返回一个实例,__init__初始化它,并且有一个清晰的方法来区分这两个进程很方便。没错,__new__可以进行初始化,它可能会返回一个现有实例而不是分配一个新实例(但当这种情况发生时,__init__不会自动调用)。但是__init__不应该创建一个实例:它期望传递一个它可以初始化的实例。如果您希望将这两种方法都称为构造函数,请随意,但这不是通常的 Python 约定。
标签: python initialization