Проблема с imp.load_source: у 'module' нет атрибута 'foo'
У меня есть каталог, заполненный произвольным количеством модулей, каждый из которых содержит только функцию do_stuff
, Например:
foos/
__init__.py
foo_1.py
foo_2.py
...
foo_n.py
Например, foo_1.py может быть просто:
def do_stuff(bar):
if bar.blah:
return True
return False
В другом месте кода я хочу собрать и запустить все do_stuff
функции. Я думаю, что это было бы легко с imp
модуль:
import imp
...
...
FOOS_DIR = os.path.join(MY_HOME, 'foos/')
MOD_REGEX = r'^(?!__).*\.py$'
foos = [imp.load_source(fname.split('.py')[0], FOOS_DIR)
for fname in os.listdir(FOOS_DIR)
if re.match(MOD_REGEX, fname)]
results = [foo.do_stuff('argument!') for foo in foos]
Однако это приводит к:
AttributeError: "'module' object has no attribute 'do_stuff'"
Исходя из ответа здесь, я подумал, что это путь. Если это так, возможно, мой синтаксис выключен? В конце концов, load_source
действительно прощает
(pdb) imp.load_source('not_there', FOOS_DIR)
<module 'not_there' from '/home/blah/blah/foos'>
Иначе чего мне не хватать?
1 ответ
Решение
Это действительно проблема синтаксиса! Мне нужен полный путь к файлу модуля, а не только его каталог, как второй аргумент load_source
:
Таким образом,
foos = [imp.load_source(fname.split('.py')[0], FOOS_DIR)
for fname in os.listdir(FOOS_DIR)
if re.match(MOD_REGEX, fname)]
становится
foos = [imp.load_source(fname.split('.py')[0], '%s%s' % (FOOS_DIR, fname))
for fname in os.listdir(FOOS_DIR)
if re.match(MOD_REGEX, fname)]
И это работает просто отлично!