The singleton scheme is similar to the subclass one
with the exception: Loader returns plugin instance, rather than class.
Instance is initialized on the first load, and only one instance of plugin
exists.
We need the base class to define the scheme, then inherit the plugins.
classBasePlugin(object):"""Base class for our plugin."""defexecute(self,x:int,y:int)->int:"""Plugin performs operation on two integers and returns integer."""...
classBasePlugin(object):"""Base class for our plugin."""defexecute(self,x:int,y:int)->int:"""Plugin performs operation on two integers and returns integer."""...
Define a base class for our plugins. We have no particular requirements,
so we can derive it from object.
classBasePlugin(object):"""Base class for our plugin."""defexecute(self,x:int,y:int)->int:"""Plugin performs operation on two integers and returns integer."""...
Though docstrings are advisory, it will help to navigate our code,
so describe plugin tasks and features.
classBasePlugin(object):"""Base class for our plugin."""defexecute(self,x:int,y:int)->int:"""Plugin performs operation on two integers and returns integer."""...
Our main function of the plugin, do not to forget to place the proper type hints to allow
static type checking.
classBasePlugin(object):"""Base class for our plugin."""defexecute(self,x:int,y:int)->int:"""Plugin performs operation on two integers and returns integer."""...
The main function of the plugin already should be documented.
classBasePlugin(object):"""Base class for our plugin."""defexecute(self,x:int,y:int)->int:"""Plugin performs operation on two integers and returns integer."""...
Ellipses operator (...) shows the implementation is abstract.
If missed, mypy
will complain the function doesn't return an integer value.
Then let's create a loader instance. You need only one loader instance per each type for your application. So loaders are usually singletons.
Loader is the generic type, so we must pass the exact plugin type. The instances of
BasePlugin type has the BasePlugin type. We'd placed the type into
the brackets just after the Loader.
After defining the plugin's type, we need to initialize the loader itself.
Loader has several initialization parameters, see Reference
for details. Here we consider our plugins will be in plugins folder of our applications.
Loader supports dict-like interface to access the modules. For this example, we will
use bracket notation. We use op parameter as the plugin name. Unlike the
subclass scheme, our loader returns the initialized instance directly.