Search code examples
python-3.xoopfactoryintrospection

Loader factory from allowed list of classes


I'd want to be able to dispatch the instantiation of a class depending of a parameter.

This has been asked here and the following answer provides a good solution, but the use of the globals()[name]() seems a bit ugly to me. Also, I understand how it works if the file is the main one, but not sure why it works if this module is imported somewhere else.

Now, what I'd like is to instead of being able to use all possible loader classes, to be able to define a subset of all available ones. Basically to have a list/dict to toggle the availability. The use cases are for example,

  1. I'm working on a new loader, but don't want it to be used
  2. I'd like to provide a list of the available loaders.

What I've tried, based on the previously linked answer, is to define a dict with keys as a more user friendly string and values the name of the class that acts as loader.

loaders = {'sqlite': sqlite_loader, 'mysql': mysql_loader}

class loader:
    @staticmethod
    def get_loader(name):
        return loaders[name]()

    def available_loaders(self):
        return [k for k in available_loaders.keys()]

class sqlite_loader(loader): pass

class mysql_loader(loader): pass

print(type(loader.get_loader('sqlite')))
print(type(loader.get_loader('mysql')))

This code does not work with the error that sqlite_loader is not defined. This I understand, but I'm not being able to find what to add to the loaders dictionary to make it able to find the loader classes.


Solution

  • loaders must be defined after the classes it refers to are defined. Just move the *_loader definitions to the top.