python类重写__new__,返回其他类的实例

上代码:
class A:

"""通过__new__返回其他的类"""

def __init__(self, data=None, **kwargs):

self.data = data

def __new__(cls, *args, **kwargs):

if kwargs.pop("another", False):

# 返回B类的实例

instance = B(*args, **kwargs)

return instance

return super().__new__(cls)

class B(A):

created_num = 0     #计数总共创建了多少实例

instance_list = []

def __init__(self, name=None, **kwargs):

# 将实例保存在instance_list中

self.__class__.instance_list.append(self)

# 对实例赋值id

self.instance_id = self.created_num

# 每创建一个实例,实例数 + 1

self.__class__.created_num += 1

self.name = name

super().__init__(**kwargs)

@property

def self_cls(self):

return self.instance_id, self.__class__.created_num

if name == "__main__":

b = A(data=0, name='ty', another=True)

print()

如上,我通过传递参数another=True,使A返回一个B类的实例,在print()处打断点,期望的结果是b.self_cls == (0, 1), b.instance_list中只有一个实例对象。
可是事与愿违:
python类重写__new__,返回其他类的实例
结果表明创建了两个实例,且当前实例是第二个(b.self_cls == (1, 2),但instance_list中的两个实例对象却又是同一个(内存地址相同),百思不得其解,希望能有大神帮忙解答,在此谢过。


回答:

把断点打在B.__init__
第一次调用栈是

B.__init__

A.__new__

main

第二次是

B.__init__

main

也就是说在A.__new__ return后, B.__init__又被调用了一次,
而正常的python对象创建的流程就是先new在init, 很合理.

如果想调用一次的话,改成下面这样就行了

    def __new__(cls, *args, **kwargs):

if kwargs.pop("another", False):

# 返回B类的实例

-- instance = B(*args, **kwargs)

-- return instance

++ return super().__new__(B)

return super().__new__(cls)

以上是 python类重写__new__,返回其他类的实例 的全部内容, 来源链接: utcz.com/p/938114.html

回到顶部