2016-08-26 3 views
0

Я пытаюсь проверить механизм, что одна программа python вызывает функции python, определенные в других файлах. Например, основная программа run.py,ImportError с модулем в том же каталоге

import os 
import shutil 
import ae.autoencoder 
if __name__ == '__main__': 
    main() 

, который вызывает autoencoder.py, расположенные под подкаталогом ae.

autoencoer.py является

import data.py 
# import data 

Однако, как import data.py или import data всегда будет дать следующее сообщение об ошибке,

python run.py 
Traceback (most recent call last): 
File "run.py", line 3, in <module> 
    import ae.autoencoder 
File "/home/autoencoder/ae/autoencoder.py", line 1, in <module> 
    import data.py 
ImportError: No module named 'data' 

Структура файла выглядит следующим образом: (/ дом/автоассоциатор является рабочим где находится run.py)

enter image description here

+4

Попробуйте 'из. import data' – vaultah

+4

не должен быть просто 'import data', а не' import data.py' –

+0

Возможно даже 'от импорта данных *' –

ответ

0

Возможно, даже если вы импортируете модуль data из модуля autoencoder, который находится в той же папке, он не работает, потому что путь поиска модулей всегда является контуром, содержащим первый файл, который запускается, поэтому путь run.py в твоем случае. И autoencoder, и data находятся в подкаталоге ae.

Вы импортировали autoencoder из run.py делает: import ae.autoencoder

Вы можете импортировать data таким же образом: импорт ae.data Becase он по-прежнему относится к пути run.py так что вы должны войти в каталог ae.

Если вы хотите, чтобы не упоминать папку все время, вы можете добавить каталог ae в системный путь.

Open run.py, то вам нужен модуль os, что вы уже импортированные, а также импортировать sys модуль,

затем:

sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "./ae") 

Так вы run.py файл должен выглядеть это:

import os 
import shutil 
import sys 
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "./ae") 
import autoencoder 
def main(): 
    pass 

if __name__ == "__main__": 
    main() 

И ваш autoencoder.py должен выглядеть следующим образом:

import data 

Если вы используете IDE, и вы пытаетесь метод sys.path.append он может показать, как модули autoencoder и data не найдены в IDE, но на самом деле они находятся во время выполнения после того, как их путь включен, поэтому он должен работать.


Другой способ загрузки модуля, расположенного в той же директории:

from . import module_name 

Если вам необходимо импортировать множество модулей или импортировать модули во время выполнения рекомендуется использовать имп (теперь устарел) или importlib модуль.

Для Python 3.5 и более поздней:

import importlib.util 
spec = importlib.util.spec_from_file_location("module_name", "/path/to/file") 
foo = importlib.util.module_from_spec(spec) 
spec.loader.exec_module(foo) 
foo.MyClass() 

Для Python 3.3 и 3.4:

from importlib.machinery import SourceFileLoader 

foo = SourceFileLoader("module_name", "/path/to/file").load_module() 
foo.MyClass() 

Для Python 2:

import imp 

foo = imp.load_source('module_name', '/path/to/file') 
foo.MyClass() 
+1

Благодарим вас за этот очень подробный ответ. – user288609

0

Первые вещи первых, нет необходимости добавлять .py расширение при импорте :) Это подразумевается.

Синтаксис для относительного импорта (импорт модулей в том же каталоге) стал немного более строгим между версиями 2 и 3. Python. Способ, которым вы его настроили, будет работать с Python 2.x, но я предполагаю, re running Python 3.x (вы можете проверить, запустив python --version). С Python 3 вам нужно явно использовать точку, чтобы теперь относительный импорт.

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

import data 

Лучше Python 2.5+ относительный импорт:

from . import data 

Вы должны использовать второй вариант в любом коде, вы пишете, если вы не специально ограничены использованием древние версии python.

Смежные вопросы