Reputation: 87
I use python 2.7. I need to load all modules in directory. Some modules stored in directory, some in subdirectory. Structure
dir
|
Tool1
| |
| __init.pyc__
| tool1.pyc
Tool2
| |
| __init.pyc__
| tool2.pyc
tool3.pyc
tool4.pyc
Each tool contains class with Run method. I can load tool with import then see dict.keys() it looks like:
['__all__', '__builtins__', 'glob', '__file__', 'traceback', 'GlobalTool', 'run_me', '__package__', 'sys', '__path__', 'Tool1', 'time', '__name__', 'csv', 'os', '__doc__']
Tool1 - is class name. Each class has attribute __VERSION. How I can load all modules from directory and extract classes from them and print all modules __VERSTION attribute ?
Additional code info: Tool1.py:
import sys, os, csv
from time import time
import traceback
from core.global_tool import GlobalTool
class ParseFiXEDVALUES(GlobalTool):
_tool_name = 'FIED_VALUES'
_VERSION = '0.1'
def run(self):
"""Main function"""
start_time = time()
cur = self.db.cursor()
pass
MyLoad Tool:
import os
import sys
mods_dir = '/home/test/multitool'
mods = {}
sys.path.append(mods_dir)
for module in os.listdir(mods_dir):
if '.py' in module and '.pyc' not in module:
current = module.replace('.py', '')
modules[current] = __import__(current)
Currently it shows all pyc or py files, but require directories and class routines
Upvotes: 0
Views: 921
Reputation: 42758
All you need to do, is check, if the module
is a directory with a __init__.py
file in it:
import os
import sys
import importlib
import inspect
import logging
def load_module(module_path, filename):
""" returns the module if filename is a module else None """
if filename.endswith('.py'):
module = filename[:-3]
elif os.path.exists(os.path.join(module_path, filename, '__init__.py')):
module = filename
else:
return None
try:
return importlib.import_module(module)
except:
logging.exception('Loading %s failed.' % module)
return None
class PluginManager(object):
def __init__(self):
self.modules = {}
self.classes = {}
def add_path(self, module_path):
sys.path.append(module_path)
for filename in os.listdir(module_path):
module = load_module(module_path, filename)
if module:
self.modules[module.__name__] = module
self._extract_classes(module)
sys.path.remove(module_path)
def _extract_classes(self, module):
for name in dir(module):
obj = getattr(module, name)
if inspect.isclass(obj):
if hasattr(obj, '_VERSION'):
version = getattr(obj, '_VERSION')
logging.info("Found %s.%s %s" % (module.__name__, name, version))
self.classes[name] = obj
logging.getLogger().level = logging.INFO
plugins = PluginManager()
plugins.add_path('/home/test/multitool')
Upvotes: 1