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中只有一个实例对象。
可是事与愿违:
结果表明创建了两个实例,且当前实例是第二个(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