本文介绍了dict属性“类型"以选择数据类的子类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程

@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"的"Constructor" -其他所有可能的类型"吗?

and that the output will be the class Csv or Parquet. I understand that if you initiate the class source you just "upload" the parameters with the method "from dict", but is there any posibility in doing this by some type of inheritence without using a "Constructor" which makes a if-else if-else over all possible 'types'?

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

Pureconfig, a Scala Library, creates different case classes when the attribute 'type' has the name of the desired subclass. In Python this is possible?

推荐答案

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

You can build a helper that picks and instantiates the appropriate subclass.

def from_data(data: dict, tp: type):
    """Create the subtype of ``tp`` for the given ``data``"""
    subtype = [
        stp for stp in tp.__subclasses__()  # look through all subclasses...
        if stp.__name__ == data['type']     # ...and select by type name
    ][0]
    return subtype(**data)  # instantiate the subtype

可以使用您的数据和要选择的基类来调用它:

This can be called with your data and the base class from which to select:

>>> 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=',')


如果您需要经常运行它,则值得构建一个dict来优化子类型查找.一种简单的方法是在基类中添加一个方法,并将查找存储在其中:


If you need to run this often, it is worth building a dict to optimise the subtype lookup. A simple means is to add a method to your base class, and store the lookup there:

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

    @classmethod
    def from_data(cls, data: dict):
        if not hasattr(cls, '_lookup'):
            cls._lookup = {stp.__name__: stp for stp in cls.__subclasses__()}
        return cls._lookup[data["type"]](**data)

这可以直接在基类上调用:

This can be called directly on the base class:

>>> Source.from_data({'type': 'Csv', 'label': 'events', 'path': '/.../test.csv', 'csv_path': '../../result.csv', 'delimiter':','})
Csv(type='Csv', label='events', path='/.../test.csv', csv_path='../../result.csv', delimiter=',')

这篇关于dict属性“类型"以选择数据类的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-27 21:30