Package: dynamic-factory
Table of contentTable of contentOverviewInstallationUsage tutorialSetupQuick startGroupsFunctions with argumentsAliasesLimitationsToDoOverviewdynamic_factoryis package for dynamic implementations of factory pattern. Currently it has implemented only one class.FuncFactorythat is designed to work with functions. Project repo can be found ongithub pageand package can be found onpypi page.InstallationVia pip:pipinstalldynamic-factoryVia poetry:poetryadddynamic-factoryUsage tutorialSetupLets define two python files./src1.pyand./src2.py# ./src1.pydeffunc1():print("greetings from src1 func1")deffunc2(arg):print(f"greetings from src1 func2 with arg{arg}")deffunc12():print("greetings from src1 func12")defunregistered_func(arg):print(f"greetings from src1 unregistered_func with arg{arg}")# ./src2.pydeffunc1():print("greetings from src2 func1")deffunc2(arg):print(f"greetings from src2 func2 with arg{arg}")Quick startIf you want to register those functions in factory, decorate them with@FuncFactory.register()method.It has two argumentsaliasoptional identifier that you can use instead of function name to execute function from factory levelgrouphelp distinguish which factory should register which function. If you use only one factory, don't have to change it.
After that functions will be visible from factory.# ./src1.pyfromdynamic_factoryimportFuncFactory@FuncFactory.register()deffunc1():print("greetings from src1 func1")@FuncFactory.register(group="TWO")deffunc2(arg):print(f"greetings from src1 func2 with arg{arg}")@FuncFactory.register()@FuncFactory.register(group="TWO")deffunc12():print("greetings from src1 func12")defunregistered_func(arg):print(f"greetings from src1 unregistered_func with arg{arg}")# ./src2.pyfromdynamic_factoryimportFuncFactory@FuncFactory.register(alias="src2_func1")deffunc1():print("greetings from src2 func1")@FuncFactory.register(alias="func_two",group="TWO")deffunc2(arg):print(f"greetings from src2 func2 with arg{arg}")To create factory simply initializeFuncFactoryobject.fromdynamic_factoryimportFuncFactoryimportsrc1importsrc2base_factory=FuncFactory([src1])print("base factory registered aliases:",*base_factory.registered_aliases)foraliasinbase_factory.registered_aliases:base_factory.execute(alias)base factory registered aliases: func1 func12
greetings from src1 func1
greetings from src1 func12Note thatbase_factorydon't recorded functions fromsrc2, thats happened becausescr2was not passed as argument in initialization. To fix that just extendmoduleslist:func1_factory=FuncFactory([src1,src2])print("func1 factory registered aliases:",*func1_factory.registered_aliases)foraliasinfunc1_factory.registered_aliases:func1_factory.execute(alias)func1 factory registered aliases: func1 func12 src2_func1
greetings from src1 func1
greetings from src1 func12
greetings from src2 func1GroupsFactories only register functions that belong to the same group as factory. If you want create more factories it may be good practice to define new groups. To define new group simply pass new unique string in register decorator. If you wish to create single function that belong to two group simply add two decorators like in./src1.py:func12example.func2_factory=FuncFactory([src1,src2],group="TWO")print("func2 factory registered aliases:",*func2_factory.registered_aliases)func2_factory.execute("func12")func2 factory registered aliases: func12 func2 func_two
greetings from src1 func12Functions with argumentsIf you want execute functions with arguments pass them toFuncFactory.executefunction asargsandkwargsfunc2_factory.execute("func2","argument")func2_factory.execute("func_two",arg=123)greetings from src1 func2 with arg argument
greetings from src2 func2 with arg 123AliasesDefault alias for function is its name. but if you prefer it is possible to change it during registration process withaliasparam. Sometimes it is necessary like in./src2.py:func1because it has the same name as./src1.py:func1, so without alias those functions would overwrite each other.LimitationsCurrent implementation is adding field to functions that store record metadata, keep it in mind if you would do some advanced function manipulations like iteration troughfunc.__dict__ToDoWarn user if he have the same alias for two different functions.implement__getitem__that will access to factory function by alias.