问题描述
我有以下课程
@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属性“类型"以选择数据类的子类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!