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?
CodePudding user response:
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 = ''
CodePudding user response:
from typing import NamedTuple
fields = {f'f{i}': str for i in range(5)}
foo = NamedTuple('foo', **fields)
print(foo.__annotations__)
# {'f0': str, 'f1': str, 'f2': str, 'f3': str, 'f4': str}
CodePudding user response:
Consider using the namedtuple() factory function from the collections module. As shown in the documentation, it is well suited to supplying the field names as data:
from collections import namedtuple
A = namedtuple('A', ('f1'))
B = namedtuple('B', A._fields ('f2', 'f3', 'f4'))
Optionally default values can given as well:
Person = namedtuple('Person', ('name', 'age', 'points'), defaults=(0, 0))
Annotations can be added dynamically using the same technique as in the code for NamedTuple:
types = {'name': str, 'age': int, 'points': int}
Person.__annotations__ = Person.__new__.__annotations__ = types
Dynamically added types will show-up in tool tips, help(), and calls to inspect.get_signature(). Static type checkers such as MyPy may have trouble with dynamically generated information.