Python get the name of all fields in a dataclass
Question:
I am trying to write a function to log dataclasses I would like to get the name of all fields in the dataclass and print the value to each (similar to how you might write a function to print a dictionary)
i.e.
@dataclasses.dataclass
class Test:
a: str = "a value"
b: str = "b value"
test = Test()
def print_data_class(dataclass_instance):
fields = # get dataclass fileds
for field in fields:
print(f{field}: {dataclass.field})
print_data_class(test)
-->
"a" : "a value"
"b" : "b value"
However I haven’t been able to find how to get the fields of a dataclass, does anyone know how this could be done?
Thanks
Answers:
use the __dict__
property
def print_data_class(dataclass_instance):
fields = [(attribute, value) for attribute, value in dataclass_instance.__dict__.items()]
for field in fields:
print("{}: {}".format(*field))
This example shows only a name, type and value, however, __dataclass_fields__
is a dict of Field
objects, each containing information such as name
, type
, default value
, etc.
Using dataclasses.fields()
Using dataclasses.fields()
you can access fields you defined in your dataclass.
fields = dataclasses.fields(dataclass_instance)
Using inspect.getmembers()
Using inspect.getmembers()
you can access all fields in your dataclass.
members = inspect.getmembers(type(dataclass_instance))
fields = list(list(filter(lambda x: x[0] == '__dataclass_fields__', members))[0][1].values())
Complete code solution
import dataclasses
import inspect
@dataclasses.dataclass
class Test:
a: str = "a value"
b: str = "b value"
def print_data_class(dataclass_instance):
# option 1: fields
fields = dataclasses.fields(dataclass_instance)
# option 2: inspect
members = inspect.getmembers(type(dataclass_instance))
fields = list(list(filter(lambda x: x[0] == '__dataclass_fields__', members))[0][1].values())
for v in fields:
print(f'{v.name}: ({v.type.__name__}) = {getattr(dataclass_instance, k)}')
print_data_class(Test())
# a: (str) = a value
# b: (str) = b value
print_data_class(Test(a="1", b="2"))
# a: (str) = 1
# b: (str) = 2
I am trying to write a function to log dataclasses I would like to get the name of all fields in the dataclass and print the value to each (similar to how you might write a function to print a dictionary)
i.e.
@dataclasses.dataclass
class Test:
a: str = "a value"
b: str = "b value"
test = Test()
def print_data_class(dataclass_instance):
fields = # get dataclass fileds
for field in fields:
print(f{field}: {dataclass.field})
print_data_class(test)
-->
"a" : "a value"
"b" : "b value"
However I haven’t been able to find how to get the fields of a dataclass, does anyone know how this could be done?
Thanks
use the __dict__
property
def print_data_class(dataclass_instance):
fields = [(attribute, value) for attribute, value in dataclass_instance.__dict__.items()]
for field in fields:
print("{}: {}".format(*field))
This example shows only a name, type and value, however, __dataclass_fields__
is a dict of Field
objects, each containing information such as name
, type
, default value
, etc.
Using dataclasses.fields()
Using dataclasses.fields()
you can access fields you defined in your dataclass.
fields = dataclasses.fields(dataclass_instance)
Using inspect.getmembers()
Using inspect.getmembers()
you can access all fields in your dataclass.
members = inspect.getmembers(type(dataclass_instance))
fields = list(list(filter(lambda x: x[0] == '__dataclass_fields__', members))[0][1].values())
Complete code solution
import dataclasses
import inspect
@dataclasses.dataclass
class Test:
a: str = "a value"
b: str = "b value"
def print_data_class(dataclass_instance):
# option 1: fields
fields = dataclasses.fields(dataclass_instance)
# option 2: inspect
members = inspect.getmembers(type(dataclass_instance))
fields = list(list(filter(lambda x: x[0] == '__dataclass_fields__', members))[0][1].values())
for v in fields:
print(f'{v.name}: ({v.type.__name__}) = {getattr(dataclass_instance, k)}')
print_data_class(Test())
# a: (str) = a value
# b: (str) = b value
print_data_class(Test(a="1", b="2"))
# a: (str) = 1
# b: (str) = 2