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=',')
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=',')
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…