1

I have a dataclass with typed attributes, using types I defined as seen below:

from dataclasses import dataclass

PositiveFloatType = NewType("PositiveFloat", float)

@dataclass(init=False, frozen=True)
class Foo:
    bar: PositiveFloatType = 1

On runtime, I'd like to get to the type of Foo.bar. I.e., I'd like to find all attributes of class Foo, and know their type names, in case of Foo.bar - get "PositiveFloatType".

I tried using inspect to no avail. Is there any way to do this?

Georgy
  • 12,464
  • 7
  • 65
  • 73
IBS
  • 165
  • 8

2 Answers2

2

That's what the dataclasses module provides the fields function for:

from dataclasses import fields

for f in fields(Foo):
    print(f.name, f.type.__name__)
IBS
  • 165
  • 8
deceze
  • 510,633
  • 85
  • 743
  • 889
  • Just a warning, `f.type` will be a string if you use `from __future__ import annotations` anywhere. – wakey Nov 11 '20 at 14:12
  • Not *anywhere*, but *within that file that defines the dataclass*. And yes, since that will be the default behaviour sometime soonish, your code should expect that. – deceze Nov 11 '20 at 14:13
  • Absolutely correct, thanks for the clarification – wakey Nov 11 '20 at 14:23
0

Just as an alternative, taking into account the fact that f.type can be a string, and I assume you actually want the concrete class object.

from typing import Any, Type, get_type_hints

def get_field_type(data_class: Type[Any], field_name: str) -> Type[Any]:
   return get_type_hints(data_class)[field_name]   
wakey
  • 2,283
  • 4
  • 31
  • 58