Python 3.7 introduces new feature called data classes.
from dataclasses import dataclass
@dataclass
class MyClass:
id: int = 0
name: str = ''
When using type hints (annotation) in function parameters, you can easily get annotated types using inspect module. How can I get dataclass field types?
Get All Fields From Data ClassThere is an in-built function called _dataclass_fields that is called on the class object and it returns all the field the class contains. This method returns a dictionary of all the field information of the object.
DataClass in Python DataClasses are like normal classes in Python, but they have some basic functions like instantiation, comparing, and printing the classes already implemented. Parameters: init: If true __init__() method will be generated. repr: If true __repr__() method will be generated.
Classes commonly contains data field to store the data and methods for defining behaviors. Also every class in python contains a special method called initializer (also commonly known as constructors), which get invoked automatically every time new object is created.
Inspecting __annotations__
gives you the raw annotations, but those don't necessarily correspond to a dataclass's field types. Things like ClassVar and InitVar show up in __annotations__
, even though they're not fields, and inherited fields don't show up.
Instead, call dataclasses.fields
on the dataclass, and inspect the field objects:
field_types = {field.name: field.type for field in fields(MyClass)}
Neither __annotations__
nor fields
will resolve string annotations. If you want to resolve string annotations, the best way is probably typing.get_type_hints
. get_type_hints
will include ClassVars and InitVars, so we use fields
to filter those out:
resolved_hints = typing.get_type_hints(MyClass)
field_names = [field.name for field in fields(MyClass)]
resolved_field_types = {name: resolved_hints[name] for name in field_names}
from dataclasses import dataclass
@dataclass
class MyClass:
id: int = 0
name: str = ''
myclass = MyClass()
myclass.__annotations__
>> {'id': int, 'name': str}
myclass.__dataclass_fields__
>> {'id': Field(name='id',type=<class 'int'>,default=0,default_factory=<dataclasses._MISSING_TYPE object at 0x0000000004EED668>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),_field_type=_FIELD),
'name': Field(name='name',type=<class 'str'>,default='',default_factory=<dataclasses._MISSING_TYPE object at 0x0000000004EED668>,init=True,repr=True,hash=None,compare=True,metadata=mappingproxy({}),_field_type=_FIELD)}
on a side note there is also:
myclass.__dataclass_params__
>>_DataclassParams(init=True,repr=True,eq=True,order=False,unsafe_hash=False,frozen=False)
The dataclasses.py is the module which provides decorator and functions for generating regular class methods by using of the field annotations. Which means that after processing class, the user defined fields shall be formed using PEP 526 Syntax of Variable annotations. The module annotations is accessible as __annotations__
.
According to the Runtime effects of type annotations the annotated types is accessible via __annotations__
attribute or by usage of the typing.get_type_hints, the last one the recommended.
Please see some code samples below:
from typing import Dict, ClassVar, get_type_hints
from dataclasses import dataclass
@dataclass
class Starship:
hitpoints: int = 50
get_type_hints(Starship) // {'hitpoints': int}
Starship.__annotations__ // {'hitpoints': int}
dataclasses.__annotations__ // The annotations of the dataclasses module.
get_type_hints(get_type_hints)
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