Проблема с 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)] 

И это работает просто отлично!

Другие вопросы по тегам