dict属性'type'以选择数据类的子类

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

我有以下课程

@dataclass_json
@dataclass
class Source:
    type: str =None
    label: str =None
    path: str = None

和两个子类:

@dataclass_json
@dataclass
class Csv(Source):
    csv_path: str=None
    delimiter: str=';'

@dataclass_json
@dataclass
class Parquet(Source):
    parquet_path: str=None

现在给字典:

parquet={type: 'Parquet', label: 'events', path: '/.../test.parquet', parquet_path: '../../result.parquet'}
csv={type: 'Csv', label: 'events', path: '/.../test.csv', csv_path: '../../result.csv', delimiter:','}

现在我想做类似的事情

Source().from_dict(csv) 

并且输出将为Csv或Parquet类。我知道,如果您启动类源,您只是使用“ from dict”方法“上载”参数,但是通过某种类型的继承来执行此操作是否有可能,而无需使用“ if-else if”的“构造函数” -其他所有可能的“类型”吗?

Pureconfig,一个Scala库,当属性'type'具有所需子类的名称时,会创建不同的案例类。在Python中这可能吗?

python json inheritance subclass python-dataclasses
2个回答
1
投票

您可以构建一个选择并实例化适当子类的帮助器。

def from_data(data: dict, tp: type):
    """Create the subtype of ``tp`` for the given ``data``"""
    subtype = [stp for stp in tp.__subclasses__() if stp.__name__ == data['type']][0]
    return subtype(**data)

可以用您的数据和从中选择的基类来调用:

>>> from_data(
...     {'type': 'Csv', 'label': 'events', 'path': '/.../test.csv', 'csv_path': '../../result.csv', 'delimiter':','},
...     Source,
... )
Csv(type='Csv', label='events', path='/.../test.csv', csv_path='../../result.csv', delimiter=',')
© www.soinside.com 2019 - 2024. All rights reserved.