I have the following code in Python:
JavaScript
x
14
14
1
class ModuleA:
2
"""This is a reusable element to compose larger designs with"""
3
4
5
class ModuleB:
6
"""Another reusable element"""
7
8
9
class MyDesign:
10
a: ModuleA
11
b0: ModuleB
12
b1: ModuleB
13
b2: ModuleB
14
The type hints are used upon instantiation of MyDesign
to dynamically add instances of the various Modules. I chose this syntax because the class MyDesign
is really just a “template” defining what Modules it’s composed of, but the instantiation of modules needs some arguments only available when MyDesign
is being instantiated.
I would like to simplify the definition of MyDesign
into something like
JavaScript
1
8
1
class MyDesign:
2
a: ModuleA
3
4
5
# define repetitive patterns in a loop
6
for i in range(2):
7
MyDesign.__type_hints__[f"b{i}"] = ModuleB
8
Is this possible?
Advertisement
Answer
Basically what you want is to dynamically modify the type hints in a class. You can achieve that by modifying the annotations__ property of the class like so:
JavaScript
1
23
23
1
from typing import get_type_hints
2
3
class ModuleA:
4
"""This is a reusable element to compose larger designs with"""
5
6
7
class ModuleB:
8
"""Another reusable element"""
9
10
11
class MyDesign:
12
a: ModuleA
13
b0: ModuleA
14
b1: ModuleA
15
b2: ModuleA
16
17
if __name__ == '__main__':
18
print(get_type_hints(MyDesign))
19
for i in range(2):
20
MyDesign.__annotations__[f"b{i}"] = ModuleB
21
22
print(get_type_hints(MyDesign))
23
result of running this code:
JavaScript
1
3
1
{'a': <class '__main__.ModuleA'>, 'b0': <class '__main__.ModuleA'>, 'b1': <class '__main__.ModuleA'>, 'b2': <class '__main__.ModuleA'>}
2
{'a': <class '__main__.ModuleA'>, 'b0': <class '__main__.ModuleB'>, 'b1': <class '__main__.ModuleB'>, 'b2': <class '__main__.ModuleA'>}
3
if you want to add the class members dynamically you can use this code:
JavaScript
1
5
1
for i in range(2):
2
MyDesign.a = lambda: None
3
setattr(MyDesign.a, f"b{i}", None)
4
MyDesign.__annotations__[f"b{i}"] = ModuleB
5