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_data
on 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_data
is 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_mode
options:* **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_data
keys.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.
-