Учитывая следующий пример макета:
test/
test.py
formats/
__init__.py
format_a.py
format_b.py
Я пытаюсь заархивировать то, что всякий раз, когда я import formats
, __init__.py
ищет все доступные модули в подкаталоге formats
, загружает их и делает их доступными (прямо сейчас просто через переменную, supported_formats
). Если есть лучший, более питонический или иной подход к динамической загрузке содержимого во время выполнения, основанный на физических доступных файлах, пожалуйста, сообщите.
Мой подход
Я пробовал что-то вроде этого (в __init__.py
):
supported_formats = [__import__(f[:f.index('.py')]) for f in glob.glob('*.py')]
Пока я просто заставляю его работать, когда запускаю __init__.py
из командной строки (из subdir форматов или из других каталогов). Но когда я импортирую его из test.py
, он выдается мне вот так:
ImportError: No module named format_a.py
То же самое, когда я импортирую его из интерпретатора python, когда я запускаю интерпретатор в другом каталоге, кроме подкаталога formats
.
Вот весь код. Он также ищет определенный класс и хранит один экземпляр каждого класса в dict, но основная часть, которую я не получаю, - динамическая загрузка модулей:
def dload(get_cls=True, get_mod=True, key=None, fstring_mod='*.py', fstring_class=''):
if p.dirname(__file__):
path = p.split(p.abspath(__file__))[0]
fstring_mod = p.join(path, fstring_mod)
print >> sys.stderr, 'Path-Glob:', fstring_mod
modules = [p.split(fn)[1][:fn.index('.py')] for fn in glob.glob(fstring_mod)]
print >> sys.stderr, 'Modules:', ', '.join(modules)
modules = [__import__(m) for m in modules]
if get_cls:
classes = {} if key else []
for m in modules:
print >> sys.stderr, "-", m
for c in [m.__dict__[c]() for c in m.__dict__ if c.startswith(fstring_class)]:
print >> sys.stderr, " ", c
if key:
classes[getattr(c, key)] = c
else:
classes.append(c)
if get_mod:
return (modules, classes)
else:
return classes
elif get_mod:
return modules
_supported_formats = dload(get_mod=False, key='fid', fstring_mod='format_*.py', fstring_class='Format')
Моя идея
Весь беспорядок с путями файловой системы и тому подобным, вероятно, в любом случае запутан. Я хотел бы справиться с этим с помощью пространств имен модулей или чего-то подобного, но сейчас я немного заблуждаюсь о том, как запускать и как обращаться к модулям, чтобы они были доступны из любого места.