I wrote a class BaseRegistry that uses a classmethod as a decorator to register other classes with a string name in a class attribute dictionary registered.
This dictionary is used to return the class associated to the string name given to its __new__ method.
This works quite well but now, I would like to create several Registries of this kind without duplicating code. Of course, if I inherit from BaseRegistry, the dictionary is shared between all subclasses which is not what I want.
I can not figure out how to achieve this “templating”.
Below a code example:
class BaseRegistry:
registered = {}
@classmethod
def add(cls, name):
def decorator(function):
cls.registered[name] = function
return function
return decorator
def __new__(cls, name):
return cls.registered[name]
class RegistryOne(BaseRegistry):
pass
class RegistryTwo(BaseRegistry):
pass
@RegistryOne.add("the_one")
class Example1:
def __init__(self, scale_factor=1):
self.scale_factor = scale_factor
@RegistryOne.add("the_two")
class Example2:
def __init__(self, scale_factor=2):
self.scale_factor = scale_factor
if __name__ == "__main__":
the_one = RegistryOne("the_one")()
print(f"{the_one.scale_factor=}")
assert RegistryOne.registered != RegistryTwo.registered
Of course, I would like to find a solution to make this code works but I am also opened to any alternative implementation of BaseRegistry that would achieve the same goal.
EDIT:
With this implementation, Pylint complains about the line:
the_one = RegistryOne("the_one")()
With this message:
E1102: RegistryOne('the_one') is not callable (not-callable)
One approach would be to define a
__init_subclass__method for the base class to initialize each subclass with its ownregistereddict:Demo: https://ideone.com/6SaHG3