I have a package of plug-in style modules. It looks like this:
/Plugins /Plugins/__init__.py /Plugins/Plugin1.py /Plugins/Plugin2.py etc...
Each .py file contains a class that derives from PluginBaseClass
. So I need to list every module in the Plugins
package and then search for any classes that implement PluginBaseClass
. Ideally I want to be able to do something like this:
for klass in iter_plugins(project.Plugins):
action = klass()
action.run()
I have seen some other answers out there, but my situation is different. I have an actual import to the base package (ie: import project.Plugins
) and I need to find the classes after discovering the modules.
Scanning modules isn't good idea. If you need class registry you should look at metaclasses or use existing solutions like zope.interface. Simple solution through metaclasses may look like that:
from functools import reduce
class DerivationRegistry(type):
def __init__(cls,name,bases,cls_dict):
type.__init__(cls,name,bases,cls_dict)
cls._subclasses = set()
for base in bases:
if isinstance(base,DerivationRegistry):
base._subclasses.add(cls)
def getSubclasses(cls):
return reduce( set.union,
( succ.getSubclasses() for succ in cls._subclasses if isinstance(succ,DerivationRegistry)),
cls._subclasses)
class Base(object):
__metaclass__ = DerivationRegistry
class Cls1(object):
pass
class Cls2(Base):
pass
class Cls3(Cls2,Cls1):
pass
class Cls4(Cls3):
pass
print(Base.getSubclasses())
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With