patternpythonModerate
List all classes in a package directory
Viewed 0 times
directorypackageallclasseslist
Problem
I have a package directory
The structure of
And in
Running it from an interactive Python shell, one directory below
So it works as expected, but
pkg with several classes that I would like to build into a convenient dict property.The structure of
pkg/ looks like:pkg/base.py:class _MyBase(object):
passpkg/foo.py:from .base import _MyBase
class Foo(_MyBase):
passAnd in
pkg/__init__.py, it is a bit clunky, but once pkg is imported, a all_my_base_classes dict is built with a key of the class name, and value of the class object. The classes are all subclasses of pkg.base._MyBase.import os
import sys
import pkgutil
import base
# I don't want to import foo, bar, or whatever other file is in pkg/
all_my_base_classes = {}
pkg_dir = os.path.dirname(__file__)
for (module_loader, name, ispkg) in pkgutil.iter_modules([pkg_dir]):
exec('import ' + name)
pkg_name = __name__ + '.' + name
obj = sys.modules[pkg_name]
for dir_name in dir(obj):
if dir_name.startswith('_'):
continue
dir_obj = getattr(obj, dir_name)
if issubclass(dir_obj, base._MyBase):
all_my_base_classes[dir_name] = dir_objRunning it from an interactive Python shell, one directory below
pkg/:>>> import pkg
>>> pkg.all_my_base_classes
{'Foo': }So it works as expected, but
pkg/__init__.py is pretty terrible looking. How can it be better?Solution
Since the classes are all subclasses of
For importing the modules, I followed the advice of Nihathrael.
_MyBase, they can be accessed via _MyBase.__subclasses__() after they have been imported:for (module_loader, name, ispkg) in pkgutil.iter_modules([pkg_dir]):
importlib.import_module('.' + name, __package__)
all_my_base_classes = {cls.__name__: cls for cls in base._MyBase.__subclasses__()}For importing the modules, I followed the advice of Nihathrael.
Code Snippets
for (module_loader, name, ispkg) in pkgutil.iter_modules([pkg_dir]):
importlib.import_module('.' + name, __package__)
all_my_base_classes = {cls.__name__: cls for cls in base._MyBase.__subclasses__()}Context
StackExchange Code Review Q#70268, answer score: 16
Revisions (0)
No revisions yet.