DictDataClass¶
-
class
privex.helpers.collections.DictDataClass[source]¶ This is a base class for use with Python 3.7+
dataclass‘s, designed to make dataclasses more interoperable with existing dictionaries, and allows them to be used like dictionaries, similar toDictable, but more powerful / flexible.The most notable difference between this and
Dictable- is that DictDataClass uses the attributeraw_dataon your dataclass to store any excess attributes when your dataclass is initialised from a dictionary withfrom_dict()orfrom_list(), allowing you to retrieve any dictionary keys which couldn’t be stored on your dataclass instance.Basic Example:
>>> from dataclasses import dataclass, field >>> from privex.helpers import DictDataClass, DictObject >>> from typing import Union >>> >>> @dataclass >>> class ExampleDataclass(DictDataClass): ... example: str = 'hello world' ... lorem: int = 999 ... raw_data: Union[dict, DictObject] = field(default_factory=DictObject, repr=False) ... ### ^ The raw, unmodified data that was passed as kwargs, as a dictionary ... ### For DictDataClass to work properly, you must include the raw_data dataclass field in your dataclass. ... >>> edc = ExampleDataclass.from_dict(dict(example='test', hello='this is an example')) >>> edc.example 'test' >>> dict(edc) {'example': 'test', 'lorem': 999}
Thanks to
raw_data- you can access any extraneous items contained within the dictionary used infrom_dict()as if they were part of your dataclass. You can also access and set any attribute using standard dictionary item syntax with square brackets like so:>>> edc.hello # This is not in the original dataclass attributes, but is proxied from raw_data 'this is an example' >>> edc['hello'] # Also works with item / dict syntax 'this is an example' >>> edc['hello'] = 'world' # You can set attributes using "key" / dict-like syntax >>> edc.hello 'world' >>> edc.hello = 'test' # You can also set raw_data keys using standard attribute dot-notation syntax. >>> edc['hello'] 'test'
Dictionary casting modes / ``__iter__`` configuration modes
There are a total of four (4)
dict`conversion modes that you may use for a given class.These modes control whether
raw_datais used when an instance is being casted viadict(obj), the order in which it’s merged with the instance attributes, along with the option to include just the dataclass attributes, or just the raw_data.Available
DictConfig.dict_convert_modeoptions:* **Fallback / Dataclass / Instance Attributes Only** - When ``dict_convert_mode`` is empty (``None`` or ``""``), or it can't be matched against a pre-defined conversion mode, when an instance is converted into a :class:`.dict` - only the attributes of the instance are used - :attr:`.raw_data` keys are ignored. ``dict_convert_mode`` settings: ``None``, ``""``, ``"none"`` or any other invalid option. * Raw Data Only ( ``raw`` / ``raw_data`` ) - When this mode is used, converting the instance to a ``dict`` will effectively just return ``raw_data``, while still enforcing the ``dict_exclude`` and ``dict_listify`` settings. ``dict_convert_mode`` settings: ``"raw"``, ``"raw_data"``, ``"rawdata"``, or any other value beginning with ``raw`` * Merge with Dataclass Priority - In this mode, both :attr:`.raw_data` and the instance's attributes are used when converting into a :class:`.dict` - first the :attr:`.raw_data` dictionary is taken, and we merge the instance attributes on top of it. This means the instance/dataclass attributes take priority over the ``raw_data`` attributes, which will generally result in only ``raw_data`` keys which don't exist on the instance having their values used in the final ``dict``. ``dict_convert_mode`` settings: ``"merge_dc"`` / ``"merge_ins"`` / ``"merge_dataclass"`` * Merge with :attr:`.raw_data` Priority - In this mode, both :attr:`.raw_data` and the instance's attributes are used when converting into a :class:`.dict` - first the instance attributes are converted into a dict, then we merge the :attr:`.raw_data` dictionary on top of it. This means the :attr:`.raw_data` keys take priority over the instance/dataclass attributes, which will generally result in only instance attributes which don't exist in ``raw_data`` having their values used in the final ``dict``. ``dict_convert_mode`` settings: ``"merge_rd"`` / ``"merge_raw"`` / ``"merge_raw_data"``
By default, the conversion mode is set to
merge_dc, which means when an instance is converted into adict- the dataclass instance attributes are merged on top of the raw_data dictionary, meaning raw_data is included, but dataclass attributes take priority overraw_datakeys.Changing the conversion mode
>>> from dataclasses import dataclass, field >>> >>> @dataclass >>> class MyDataclass(DictDataClass): ... class DictConfig: ... dict_convert_mode = 'merge_dc' ... ... hello: str ... lorem: str = 'ipsum' ... raw_data: Union[dict, DictObject] = field(default_factory=DictObject, repr=False) >>> dc = MyDataclass.from_dict(dict(hello='test', example=555, test='testing')) >>> dc.hello 'test' >>> dc.hello = 'replaced' >>> dict(dc) {'hello': 'replaced', 'example': 555, 'test': 'testing', 'lorem': 'ipsum'} >>> dc.DictConfig.dict_convert_mode = 'merge_raw' {'hello': 'test', 'lorem': 'ipsum', 'example': 555, 'test': 'testing'} >>> dc.DictConfig.dict_convert_mode = None {'hello': 'replaced', 'lorem': 'ipsum'}
-
__init__() Initialize self. See help(type(self)) for accurate signature.
-