This is a question about which of these methods would be considered as the most Pythonic. I'm not looking for personal opinions, but, instead, what is idiomatic. My background is not in Python, so this will help me.
I'm working on a Python 3 project which is extensible. The idea is similar to the factory pattern, except it is based on functions.
Essentially, users will be able to create a custom function (across packages and projects) which my tool can locate and dynamically invoke. It will also be able to use currying to pass arguments down (but that code is not included here)
My goal is for this to follow good-Pythonic practice. I'm torn between two strategies. And, since Python is not my expertise, I would like to know the pros/cons of the following practices:
Use a decorator
registered = {} def factoried(name): def __inner_factory_function(fn): registered[name] = fn return fn return __inner_factory_function def get_function(name): return registered[name]
Then, the following function is automatically registered...
@factoried('foo') def build_foo(): print('hi')
This seems reasonable, but does appear slightly magical to those who are not familiar with decorators.
Force sub-classing of an abstract class and use
__subclasses__()
If subclasses are used, there's no need for registration. However, I feel like this forces classes to be defined when a full class may be unnecessary. Also, the use of
.__subclasses__()
under the hood could seem magical to consumers as well. However, even Java can be used to search for classes with annotations.Explicit registration
Forget all of the above and force explicit registration. No decorators. No subclasses. Just something like this:
def build_foo(): # ... factory.register('foo', build_foo)