假设以下代码:
class NumStorage(object):
def __new__(cls, *nargs):
name = cls.__name__
parents = cls.__bases__
kwargs = {'num%i' % pos : i for pos, i in enumerate(nargs, 1)}
if any(kwargs.values()) and len(kwargs.values()) >= 2:
end = len(kwargs.values()) + 1
kwargs['num%i' % end] = sum(kwargs.values())
self = type(name, parents, kwargs)
return self
此NumStorage
对象接收任意数量的数字,如果有两个或更多数字且它们的总和加起来大于0,则会创建一个新的kwarg
键。 / p>
如果NumStorage实例的初始化可以在__new__
中进行,那么为什么python甚至需要一个__init__
?另一件令我困惑的事情;如果我们确实向__init__
类添加NumStorage
方法,那么:
class NumStorage(object):
def __new__(cls, *nargs):
name = cls.__name__
parents = cls.__bases__
kwargs = {'num%i' % pos : i for pos, i in enumerate(nargs, 1)}
if any(kwargs.values()) and len(kwargs.values()) >= 2:
end = len(kwargs.values()) + 1
kwargs['num%i' % end] = sum(kwargs.values())
self = type(name, parents, kwargs)
return self
def __init__(self, *nargs):
print("initializing")
它永远不会打印“初始化”,即使__init__
应该在__new__
之后调用,因为__new__
返回了一个对象的实例,不是吗?如果不是,我对此感到困惑是什么?
答案 0 :(得分:3)
__init__
排在第一位。 __new__
主要添加到......好吧,我会让documentation解释一下:
__new__()
主要用于允许不可变类型的子类(如int,str或tuple)自定义实例创建。它也通常在自定义元类中重写,以自定义类创建。
__init__
对于旧式的课程系统来说已经足够好了。即使你将一个“不可变的”旧式类子类化,你也只需要为超类的__init__
提供适当的参数。这并没有削减它的子类,比如tuple
。
至于__init__
未被调用:
如果
__new__()
返回 cls 的实例,则返回新实例__init__()
方法将像__init__(self[, ...])
一样被调用,其中 self 是新实例,其余参数与 被传递给__new__()
。如果
。实例的__new__()
未返回 cls 的实例,则为新的__init__()
方法不会被调用。
答案 1 :(得分:1)
python甚至需要一个
__init__
?
不,python不需要 __init__
,但如果只有__new__
,那么每次创建一个类时,你都需要弄清楚所有的进入__new__
的点点滴滴。
它使python更容易,并且更不容易出错,将两者分开。
另外,历史上__init__
位于__new__
之前。