gpt4 book ai didi

python - __new__() 不返回类实例时的继承

转载 作者:太空宇宙 更新时间:2023-11-03 17:56:32 25 4
gpt4 key购买 nike

__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 of cls, 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com