2015-10-14 2 views
2

Предположим, у меня есть две почти идентичные версии пакета mymod python, то есть mymod0 и mymod1. Каждый из этих пакетов имеет файлы init .py и foo.py, а foo.py - единственная функция printme(). Вызов mymod0.foo.printme() будет печатать «Я - mymod0», а вызов mymod1.foo.printme() будет печатать «Я - mymod1». Все идет нормально.Динамически загружать пакет в python

Но теперь мне нужно динамически импортировать либо mymod0, либо mymod1. Пользователь будет вводить либо 0, либо 1 к сценарию (как переменная «индекс»), а затем я могу создать PACKAGENAME = «MyMod» ул (индекс) +

Я попытался это:

module=importlib.import_module(module_name) 
module.foo.printme() 

Но Я получаю эту ошибку: AttributeError: объект 'module' не имеет атрибута 'foo'

Как я могу указать, что пакет теперь должен называться модулем, так что module.foo.printme() будет работать?

UPDATE: Таким образом, проще всего использовать функцию exec(). Таким образом, я могу динамически создать оператор импорта, как это:

cmdname="from mymod%s import foo" % index 
exec(cmdname) 

Тогда:

foo.printme() 

Это похоже на работу.

ответ

0

How can I specify the the package should now be referred to as module so that module.foo.printme() will work?

Вы должны убедиться, что <module_name>.__init__ импорт foo в пространство имен модуля:

#./<module_name>/__init__.py 
import foo 

, то вы можете

module=importlib.import_module(module_name) 
module.foo.printme() 

But now I need to dynamically import either mymod0 or mymod1.

Примечание это работает только в первый раз, потому что питона кэшей загруженных модулей. Если модуль изменился с момента запуска программы, используйте функцию reload function. Просто предостережение: с этим связано несколько оговорок, и это может закончиться тем, что вы не делали то, что вы намеревались.

How can I recreate this dynamically?

for i in range(0,2): 
    module_name = 'mymod%s' % i 
    module=importlib.import_module(module_name) 
    module.foo.printme() 
+0

Хорошо это близко, но то, что я хочу сделать, это динамически воссоздать этот импорт: импорт mymod0 как MyMod. Итак, здесь mymob теперь ссылается на пакет mymod0. Если я сделаю это статически, тогда я могу без проблем назвать mymod0.foo.printme(). Как я могу воссоздать это динамически? – Marc

+0

@ Маркс, пожалуйста, см. Мое редактирование. Заметьте, я не тестировал это – miraculixx