来自父数据类的属性的Python数据类继承部分

问题描述 投票:0回答:1

我构造了多个碱基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)

即,我想构造一个继承DA以及B中除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'

我该怎么办?

python python-dataclasses
1个回答
0
投票

[与@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'])

然后可以通过以下方式获得[C0

D
© www.soinside.com 2019 - 2024. All rights reserved.