![](/img/trans.png)
[英]Python Dataclasses: Mocking the default factory in a frozen Dataclass
[英]Python dataclasses inheritance part of attributes from parent dataclass
我構建了多個基礎dataclass
。 現在我想構造一個繼承自這些基類的子dataclass
類,但可能會繼承某些基類中定義的部分屬性。 示例可以是:
import dataclasses
@dataclasses.dataclass
class A:
a: int = None
b: float = None
c: str = None
@dataclasses.dataclass
class B:
d: int = None
b: float = 3.5
@dataclasses.dataclass
class C:
e: int = None
f: float = 3.5
g: int = None
@dataclasses.dataclass
class D(A, B):
def __post_init__(self):
for _field, _field_property in C.__dataclass_fields__.items():
if _field != "g":
setattr(self, _field, _field_property.default)
即,我想構造一個繼承A
和B
的子類D
,以及C
除g
之外的屬性。 檢查子類D
>>> D.__dataclass_fields__.keys() # got dict_keys(['d', 'b', 'a', 'c'])
>>> d = D(a=4, b=2, c=5, d=3.4, e=2.1, g=55)
Traceback (most recent call last):
File "<pyshell#77>", line 1, in <module>
d = D(a=4, b=2, c=5, d=3.4, e=2.1, g=55)
TypeError: __init__() got an unexpected keyword argument 'e'
和
>>> D.__dict__.keys()
dict_keys(['__module__', '__post_init__', '__doc__', '__dataclass_params__', '__dataclass_fields__', '__init__', '__repr__', '__eq__', '__hash__'])
當我將__post_init__
更改為__init__
並使用super().__init__()
進行繼承時,仍然無法獲取類C
的屬性並失去dataclass
的優勢,即,
>>> @dataclasses.dataclass
class D(A, B):
def __init__(self):
super().__init__()
for _field, _field_property in C.__dataclass_fields__.items():
if _field != "g":
setattr(self, _field, _field_property.default)
並運行
>>> d = D(a=4, b=2, c=5, d=3.4, e=2.1, g=55)
Traceback (most recent call last):
File "<pyshell#81>", line 1, in <module>
d = D(a=4, b=2, c=5, d=3.4, e=2.1, g=55)
TypeError: __init__() got an unexpected keyword argument 'a'
我該怎么辦?
如什么建議@GiacomoAlzetta類似,我突然用出來這個想法dataclasses.make_dataclass
,即生成的副本C
但不包括屬性g
,即
<<< C_part = dataclasses.make_dataclass("C_part", [(_field, _field_property.type, _field_property.default) for _field, _field_property in C.__dataclass_fields__.items() if _field != "g"])
因此我有
>>> C_part.__dataclass_fields__.keys() # dict_keys(['e', 'f'])
那么D
可以通過
>>> @dataclasses.dataclass
class D(A, B, C_part):
pass
>>> d = D(a=4, b=2, c=5, d=3.4, e=2.1, f=55)
>>> d
D(e=2.1, f=55, d=3.4, b=2, a=4, c=5)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.