简体   繁体   中英

How can I get Python 3.7 new dataclass field types?

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?

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM