I’m trying to dynamically create subclasses in Python with type:
class A: @classmethod def create_subclass(cls, name, attrs): return type(name, (cls,), attrs) for i in range(5): x = A.create_subclass("B", {"func": abs}) print(A.__subclasses__())
and here’s what I see in the output:
[<class '__main__.B'>, <class '__main__.B'>, <class '__main__.B'>, <class '__main__.B'>, <class '__main__.B'>]
Obviously, this was not my intention. Two questions in that respect:
- How does Python handles multiple classes with identical names?
- What is a pythonic way to handle it? Of course, I can look up the name in the already existing subclasses, but then how to deal with namespaces/modules?
Advertisement
Answer
Python doesn’t care overmuch about the classname, these will be different classes, you just need to have a mechanism to save and look up the classes you want.
class A: def __repr__(self): return f"{self.__class__.__name__} floor={self.floor}" @classmethod def create_subclass(cls, name, attrs): return type(name, (cls,), attrs) di_cls = {} #save them in a dictionary for i in range(5): di_cls[i] = A.create_subclass("B", {"func": abs, "floor" : i}) for i, cls in di_cls.items(): print(f"{cls()}") class config: #put them in hierarchical namespaces cls_level1 = A.create_subclass("B", {"func": abs, "floor" : 11}) class level2: cls_level2 = A.create_subclass("B", {"func": abs, "floor" : 22}) print(f"{config.cls_level1()=}") print(f"{config.level2.cls_level2()}") l1 = config.cls_level1() l2 = config.level2.cls_level2() print(f"{isinstance(l1, A)=}") print(f"{isinstance(l2, A)=}") print(f"{isinstance(l2, config.level2.cls_level2)=}") print(f"{isinstance(l2, config.cls_level1)=}")
output:
B floor=0 B floor=1 B floor=2 B floor=3 B floor=4 config.cls_level1()=B floor=11 B floor=22 isinstance(l1, A)=True isinstance(l2, A)=True isinstance(l2, config.level2.cls_level2)=True isinstance(l2, config.cls_level1)=False