我有一个我想继承的类 A,这个类有一个类方法,可以从一些数据初始化一个新实例。我无权访问 A 的代码from_data,也无法更改 A 的实现。
我想使用传递给 Afrom_data方法的相同数据来初始化 B 类的新实例。在我提出的解决方案中,我创建了 A 的新实例 __new__(...)并将其更改__class__为 B。__init__(...)然后可以像平常一样进一步初始化“B 的新实例”。它似乎有效,但我不确定这会产生某种副作用。
那么这会可靠地工作吗?有没有正确的方法来实现这一目标?
class A:
def __init__(self, alpha, beta):
self.alpha = alpha
self.beta = beta
@classmethod
def from_data(cls, data):
obj = cls(*data)
return obj
class B(A):
def __new__(cls, data):
a = A.from_data(data)
a.__class__ = cls
return a
def __init__(self, data):
pass
b = B((5, 3))
print(b.alpha, b.beta)
print(type(b))
print(isinstance(b, B))
Run Code Online (Sandbox Code Playgroud)
输出:
5 3
<class '__main__.B'>
True
Run Code Online (Sandbox Code Playgroud)
可能你的用例比我理解的更抽象,但是在 REPL 中测试,似乎通过调用父class A构造函数super()
class A:
# ...
class B(A):
def __init__(self, data):
super().__init__(*data)
b = B((5, 3))
print(b.alpha, b.beta)
print(type(b))
print(isinstance(b, B))
Run Code Online (Sandbox Code Playgroud)
也导致
5 3
<class '__main__.B'>
True
Run Code Online (Sandbox Code Playgroud)
您是否有理由不想调用super()来实例化子类的新实例?
编辑:
所以,如果你需要使用from_data构造函数......你可以做类似的事情
#... class A
class B(A):
def __init__(self, data):
a_obj = A.from_data(data)
for attr in a_obj.__dict__:
setattr(self, attr, getattr(a_obj, attr))
Run Code Online (Sandbox Code Playgroud)
但这确实很hacky...并且不能保证适用于A类对象的所有属性,特别是在__dict__函数已重载的情况下。