I have the following code in Python:
class ModuleA: """This is a reusable element to compose larger designs with""" class ModuleB: """Another reusable element""" class MyDesign: a: ModuleA b0: ModuleB b1: ModuleB b2: ModuleB
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
class MyDesign: a: ModuleA # define repetitive patterns in a loop for i in range(2): MyDesign.__type_hints__[f"b{i}"] = ModuleB
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:
from typing import get_type_hints class ModuleA: """This is a reusable element to compose larger designs with""" class ModuleB: """Another reusable element""" class MyDesign: a: ModuleA b0: ModuleA b1: ModuleA b2: ModuleA if __name__ == '__main__': print(get_type_hints(MyDesign)) for i in range(2): MyDesign.__annotations__[f"b{i}"] = ModuleB print(get_type_hints(MyDesign))
result of running this code:
{'a': <class '__main__.ModuleA'>, 'b0': <class '__main__.ModuleA'>, 'b1': <class '__main__.ModuleA'>, 'b2': <class '__main__.ModuleA'>} {'a': <class '__main__.ModuleA'>, 'b0': <class '__main__.ModuleB'>, 'b1': <class '__main__.ModuleB'>, 'b2': <class '__main__.ModuleA'>}
if you want to add the class members dynamically you can use this code:
for i in range(2): MyDesign.a = lambda: None setattr(MyDesign.a, f"b{i}", None) MyDesign.__annotations__[f"b{i}"] = ModuleB