Базовая механика импорта Python - PullRequest
0 голосов
/ 03 сентября 2018

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

project/
  A/
    __init__.py
    foo.py
  TestA/
    __init__.py
    testFoo.py

содержание testFoo:

import unittest
from A import foo

из каталога project, который я запускаю python testA/testFoo.py

Я получаю ModuleNotFoundError No module named A

У меня два вопроса: как импровизировать и запустить A.foo из TestA.testFoo и почему так трудно понять логику импорта в Python? Нет ли какой-нибудь хитрости для быстрого решения такого рода проблем, извините, я беспокою вас такими базовыми вопросами?

Ответы [ 5 ]

0 голосов
/ 03 сентября 2018

Вы определенно не можете найти A, потому что python нужно посмотреть из sys.path, PYTHONPATH, чтобы найти модуль.

И python автоматически добавит текущие значения top level script к sys.path, а не currently directory к sys.path. Поэтому, если вы добавите print(sys.path) в testFoo.py, вы увидите, что это только добавит project/TestA к sys.path.

Другое слово, project не было включено в sys.path, тогда как python может найти модуль A?

Таким образом, вам пришлось добавить папку project в sys.path самостоятельно, и это просто необходимо в top script, примерно так:

import unittest
import sys
import os
file_path = os.path.abspath(os.path.dirname(__file__)).replace('\\', '/')
lib_path = os.path.abspath(os.path.join(file_path, '..')).replace('\\', '/')
sys.path.append(lib_path)
0 голосов
/ 03 сентября 2018

Рекомендуемый путь в py3 может быть как ниже

echo $pwd
$ /home/user/project
python -m testA.testFoo

Способ выполнения модуля python -m в python - это хороший способ заменить относительные ссылки。

0 голосов
/ 03 сентября 2018

Когда вы выполняете файл, генерируется переменная среды с именем python path, python import работает с этой переменной, чтобы найти ваш файл для импорта, этот путь генерируется вместе с путем файла, который вы выполняете, и он будет искать в текущий каталог и подкаталоги, содержащие файл __init__.py, если вы хотите импортировать из каталога того же уровня, вам нужно изменить путь к Python или изменить архитектуру вашего проекта, чтобы исполняемый файл всегда находился на верхнем уровне.

вы можете включить путь к вашему пути в Python следующим образом:

import sys
sys.path.insert(0, "/path/to/file.py")

Вы можете узнать больше о системе импорта: https://docs.python.org/3/reference/import.html

На мой взгляд, лучший способ - не трогать путь python и не включать ваш тестовый каталог в каталог, где находятся проверенные файлы:

project/
  A/
    __init__.py
    foo.py
    TestA/
        __init__.py
        testFoo.py

Затем введите команду python -m unittest в каталог A или проекта, он найдет в вашем текущем и подкаталогах тест и выполнит его.

Подробнее о тестировании здесь: https://docs.python.org/3/library/unittest.html

0 голосов
/ 03 сентября 2018

Можете ли вы попробовать это?

Создать пустой файл __init__.py в подкаталоге TestA. И добавить в начале основной код

from __future__ import absolute_import

Затем импортируйте, как показано ниже:

import A.foo as testfoo
0 голосов
/ 03 сентября 2018

Сначала добавьте папку project/testA в системный pythonpath:

import sys
sys.path.insert(0, "/path/to/pythonfile")

и попробуйте импортировать снова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...