I have a basic class like this:
from typing import NamedTuple
class A(NamedTuple):
f1: str = ""
aa = A("haha")
print(aa)
Now suppose I have a list of more fields that I want to use in Class A
, essentially:
more_field_names = ['f2', 'f3', 'f4']
and I want to make Class A
look like this, but without manually typing all the field names:
class A(NamedTuple):
f1: str = ""
f2: str = ""
f3: str = ""
f4: str = ""
Is there a way to use something like list comprehension to add each field names to the Class A
definition?
I'm not entirely sure if this is what you're looking for, but you can dynamically generate the class definition to copy-paste into a python file, based on a list of fields that you want to add (assuming you have a lot of same-type fields to add):
def gen_named_tuple_schema(fields: list[str], class_name='A'):
fields = '\n'.join(f" {f}: str = ''" for f in fields)
return f'class {class_name}(NamedTuple):\n{fields}'
Then you can use it like so:
print(gen_named_tuple_schema(['f1', 'f2', 'f3', 'f4']))
Output:
class A(NamedTuple):
f1: str = ''
f2: str = ''
f3: str = ''
f4: str = ''
I would add that, even though it is technically possible to run exec()
on the generated code, I would honestly not recommend it. The reason is that type checkers won't know the type of A
by default, so they won't be able to offer field auto-completion and type checking.
For example, in my case PyCharm does not complain at all if I do this:
return_dict = {}
exec(gen_named_tuple_schema(['f1', 'f2', 'f3', 'f4']),
{'NamedTuple': typing.NamedTuple},
return_dict)
A = return_dict['A'] # my type checker: what is A?
print(A(1, '2', 3, '4')) # A(f1=1, f2='2', f3=3, f4='4')