当__new__
返回类的实例时,一切正常,我们可以创建没有问题的子类:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
return self
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
return self
def __init__(self, p3):
super().__init__(1, 2)
self.p3 = p3
a = A(1, 2)
print(a.p2) # output: 2
b = B(3)
print(b.p3) # output: 3
但是,
如果
。实例的__new__()
未返回cls
的实例,则返回新的__init__()
__init__()
方法不会被调用。
我们必须直接在__new__()
内调用super().__new__
,但当我们在子类中调用class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
self.__init__(p1, p2) # we should call __init__ directly
return [self] # return not instance
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
return self
def __init__(self, p3):
self.p3 = p3
a = A(1, 2)
print(a[0].p2) # output: 2
b = B(3) # TypeError: __init__() takes 2 positional arguments but 3 were given
print(b[0].p3)
时,这会导致错误:
A
如何解决?如果A.__new__()
没有返回类的实例,如何创建{{1}}的子类?
答案 0 :(得分:1)
如果您要手动调用它,请不要命名方法__init__
并改为使用每个类名称,或手动调用__init__
方法没有约束,直接在课堂上。
每个类名称相对容易,您可以在开头使用双下划线来通过name mangling生成特定于类的名称:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
self.__init(p1, p2) # call custom __init directly
return [self] # return not instance
def __init(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
self[0].__init(p3) # custom init
return self
def __init(self, p3):
self.p3 = p3
或直接在课堂上:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
A.__init__(self, p1, p2) # call custom __init__ unbound
return [self] # return not instance
def __init__(self, p1, p2):
self.p1 = p1
self.p2 = p2
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
B.__init__(self[0], p3) # call custom __init__ unbound
return self
def __init__(self, p3):
self.p3 = p3
如果您采用这种方式,您可以使用自定义初始化工具取消,只需在__new__
完成初始化:
class A:
def __new__(cls, p1, p2):
self = object.__new__(cls)
self.p1 = p1
self.p2 = p2
return [self] # return not instance
class B(A):
def __new__(cls, p3):
self = super().__new__(cls, 1, 2)
self[0].p3 = p3
return self
毕竟,你已经在创建时有权访问该实例,你也可以在那里初始化它。