I have the following very simple dataclass:
import dataclasses @dataclasses.dataclass class Test: value: int
I create an instance of the class but instead of an integer I use a string:
>>> test = Test('1') >>> type(test.value) <class 'str'>
What I actually want is a forced conversion to the datatype i defined in the class defintion:
>>> test = Test('1') >>> type(test.value) <class 'int'>
Do I have to write the __init__
method manually or is there a simple way to achieve this?
Data classes also make it easier to create frozen (immutable) instances, serialize instances and enforce type hints usage. The main parts of a data class are: @dataclass decorator which returns the same defined class but modified. field function which allow for per-field customizations.
dataclass module is introduced in Python 3.7 as a utility tool to make structured classes specially for storing data. These classes hold certain properties and functions to deal specifically with the data and its representation. DataClasses in widely used Python3.6.
A dataclass can very well have regular instance and class methods. Dataclasses were introduced from Python version 3.7. For Python versions below 3.7, it has to be installed as a library.
A data class is a class typically containing mainly data, although there aren't really any restrictions. It is created using the new @dataclass decorator, as follows: from dataclasses import dataclass @dataclass class DataClassCard: rank: str suit: str.
The type hint of dataclass attributes is never obeyed in the sense that types are enforced or checked. Mostly static type checkers like mypy are expected to do this job, Python won't do it at runtime, as it never does.
If you want to add manual type checking code, do so in the __post_init__
method:
@dataclasses.dataclass class Test: value: int def __post_init__(self): if not isinstance(self.value, int): raise ValueError('value not an int') # or self.value = int(self.value)
You could use dataclasses.fields(self)
to get a tuple of Field
objects which specify the field and the type and loop over that to do this for each field automatically, without writing it for each one individually.
def __post_init__(self): for field in dataclasses.fields(self): value = getattr(self, field.name) if not isinstance(value, field.type): raise ValueError(f'Expected {field.name} to be {field.type}, ' f'got {repr(value)}') # or setattr(self, field.name, field.type(value))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With