问题
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?
回答1:
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)
回答2:
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}
回答3:
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)
来源:https://stackoverflow.com/questions/51946571/how-can-i-get-python-3-7-new-dataclass-field-types