当__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
但是,
If
__new__()
does not return an instance ofcls
, then the new instance’s__init__()
method will not be invoked.
看起来我们必须直接在 __new__()
内部调用 __init__()
,但这会导致错误,当我们调用 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.__new__()
不返回类的实例,如何创建A
的子类?
最佳答案
如果您要手动调用它,请不要命名该方法 __init__
并使用每个类的名称,或手动调用 __init__
方法未绑定(bind),直接在类上。
每个类的名称相对简单,您可以在开头使用双下划线通过 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
毕竟,您在创建时已经可以访问实例,您也可以当场初始化它。
关于python - __new__() 不返回类实例时的继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28392810/