当 __new__() 不是 return class 实例时的继承
Inheritance when __new__() doesn't return instance of class
当 __new__
return 实例 class 时,一切正常,我们可以毫无问题地创建子 class:
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 of cls
, then the new
instance’s __init__()
method will not be invoked.
看起来我们必须直接在__new__()
中调用__init__()
,但这会导致错误,当我们在子class中调用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__()
不是 return class 的实例,如何创建 A
的子 class?
如果您要手动调用它,要么不要命名方法 __init__
而是使用每个 class 名称,手动 或 直接在 class.
上调用未绑定的 __init__
方法
Per-class 名称相对容易,您可以在开头使用双下划线通过 name mangling:
生成 class-specific 名称
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:
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
毕竟,您已经在创建时就可以访问该实例,您最好立即对其进行初始化。
当 __new__
return 实例 class 时,一切正常,我们可以毫无问题地创建子 class:
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__()
,但这会导致错误,当我们在子class中调用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__()
不是 return class 的实例,如何创建 A
的子 class?
如果您要手动调用它,要么不要命名方法 __init__
而是使用每个 class 名称,手动 或 直接在 class.
__init__
方法
Per-class 名称相对容易,您可以在开头使用双下划线通过 name mangling:
生成 class-specific 名称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:
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
毕竟,您已经在创建时就可以访问该实例,您最好立即对其进行初始化。