2016-12-09 5 views
1

Я хочу импортировать модуль с помощью import_module из importlib. Когда я это делаю, файлы, ссылающиеся на мой модуль, не найдены. Если я обычно импортирую свой модуль из оболочки python (не используя main.py), он работает так, как ожидалось. Кроме того, если я добавлю путь MyModule.py к sys.path, это работает, но из того, что я понимаю, я не должен это делать (прокомментирован в коде ниже).Ссылка на файл python из модуля при загрузке import_module

Как я могу загрузить загруженный файл ссылки, когда модуль загружается import_module?

У меня есть следующая структура файловой

main.py 
    subfolders 
    folder1 
     __init__.py 
     MyModule.py 
     hello.py 

Содержание main.py

from importlib import import_module 

modulename = 'subfolders.folder1.MyModule' 
print("Import module ", modulename) 
module = import_module(modulename) 
m_instance = module.MyModule() 

m_instance.module_hello() 

Содержание MyModule.py

#This is the solution that works but feels wrong 
#import os, sys 
#sys.path.append(os.path.dirname(__file__)) 

from hello import hello_world 

class MyModule(object): 
    def __init__(self): 
     print("Init MyModule") 

    def module_hello(self): 
     hello_world() 

Содержание hello.py

def hello_world(): 
    print("Hello World!") 

Когда я запускаю это я получаю:

c:\git\PythonImportTest>python main.py 
Import module subfolders.folder1.MyModule 
Traceback (most recent call last): 
    File "main.py", line 5, in <module> 
    module = import_module(modulename) 
    File "C:\Miniconda3\lib\importlib\__init__.py", line 126, in import_module 
    return _bootstrap._gcd_import(name[level:], package, level) 
    File "<frozen importlib._bootstrap>", line 986, in _gcd_import 
    File "<frozen importlib._bootstrap>", line 969, in _find_and_load 
    File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked 
    File "<frozen importlib._bootstrap>", line 673, in _load_unlocked 
    File "<frozen importlib._bootstrap_external>", line 665, in exec_module 
    File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed 
    File "c:\git\PythonImportTest\subfolders\folder1\MyModule.py", line 5, in <module> 
    from hello import hello_world 
ImportError: No module named 'hello' 

ответ

2

Сначала вы должны сделать свой subfolders каталог пакета путем размещения пустой __init__.py там. Во-вторых, вам необходимо импортировать свой модуль hello либо по абсолютному импорту, либо по относительному импорту.

Абсолютный импорт:

from subfolders.folder1.hello import hello_world 

Относительный импорт:

from .hello import hello_world 

, как вы делаете это на данный момент будет искать hello.py в вашем пакете верхнего уровня (где ваш main.py есть). Поскольку он не может быть найден там, вы получите сообщение об ошибке.

Примечание относительного импорта в Python3

Вы Propably перешли от python2 к Python3 поэтому вы получите в неприятности при использовании неявного относительно импорта. Как PEP404 говорит:

В Python 3, неявный относительный импорт в рамках пакетов больше не доступен - только абсолютный импорт и явный относительный импорт поддерживается. Кроме того, импорт звездочек (например, из x import *) составляет только , разрешенный кодом модуля.

Значение вашего кода должно работать на Python2, но для Python3 вам необходимо использовать один из указанных выше вариантов. См. Также: Changes in import statement python3

1

проблема с вашим кодом заключается в том, что вложенные папки - это папка, а не пакет. если вы используете import_module, то можно искать только в пакетах для подпакетов.

Создайте init .py в папке ваших подпапок и папке import1 там.