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?
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))