Относительный импорт - ModuleNotFoundError: нет модуля с именем x

Это первый раз, когда я действительно сел и попробовал python 3, и, похоже, терпит неудачу. У меня есть следующие два файла:

  • test.py
  • config.py

config.py имеет несколько функций, определенных в нем, а также несколько переменных. Я разделил это на следующее:

введите описание изображения здесь

Однако я получаю следующую ошибку:

ModuleNotFoundError: No module named 'config'

Я знаю, что соглашение py3 заключается в использовании абсолютного импорта:

from . import config

Однако это приводит к следующей ошибке:

ImportError: cannot import name 'config'

Итак, я не понимаю, что делать здесь... Любая помощь очень ценится.:)

Ответ 1

Как было указано в комментариях к исходному сообщению, это, казалось, проблема с интерпретатором python, который я использовал по любой причине, а не с неправильным сценарием python. Я переключился с пакета WinPython на официальный python 3.6 с python.org, и он работал отлично. спасибо за помощь всем:)

Ответ 2

TL; DR: вы не можете выполнять относительный импорт из файла выполнить, так как модуль __main__ не является частью пакета.

Абсолютный импорт - импортируйте что-то доступное на sys.path

Относительный импорт - импортировать что-то относительно текущего модуля, должен быть частью пакета

Если вы используете оба варианта точно так же, один из них должен работать. В любом случае, вот пример, который должен помочь вам понять, что происходит, добавьте еще один файл main.py с общей структурой каталогов:

.
./main.py
./ryan/__init__.py
./ryan/config.py
./ryan/test.py

И обновите test.py, чтобы узнать, что происходит:

# config.py
debug = True


# test.py
print(__name__)

try:
    # Trying to find module in the parent package
    from . import config
    print(config.debug)
    del config
except ImportError:
    print('Relative import failed')

try:
    # Trying to find module on sys.path
    import config
    print(config.debug)
except ModuleNotFoundError:
    print('Absolute import failed')


# main.py
import ryan.test

Сначала запустите test.py:

$ python ryan/test.py
__main__
Relative import failed
True

Здесь "test" - это модуль __main__ и ничего не знает о принадлежности к пакету. Однако import config должен работать, поскольку папка ryan будет добавлена ​​в sys.path.

Вместо этого запустите main.py:

$ python main.py
ryan.test
True
Absolute import failed

И здесь тест находится внутри пакета "ryan" и может выполнять относительный импорт. import config терпит неудачу, так как неявный относительный импорт не разрешен в Python 3.

Надеюсь, что это помогло.

P.S.: Если вы придерживаетесь Python 3, больше нет необходимости в файлах __init__.py.

Ответ 3

Я понял это. Очень неприятно, особенно из python2.

Вам нужно добавить модуль ., независимо от того, является он относительным или абсолютным.

Я создал настройку каталога следующим образом.

/main.py
--/lib
  --/__init__.py
  --/mody.py
  --/modx.py

modx.py

def does_something():
    return "I gave you this string."

mody.py

from modx import does_something

def loaded():
    string = does_something()
    print(string)

main.py

from lib import mody

mody.loaded()

когда я выполняю main, вот что происходит

$ python main.py
Traceback (most recent call last):
  File "main.py", line 2, in <module>
    from lib import mody
  File "/mnt/c/Users/Austin/Dropbox/Source/Python/virtualenviron/mock/package/lib/mody.py", line 1, in <module>
    from modx import does_something
ImportError: No module named 'modx'

Я запустил 2to3, а основной вывод был

RefactoringTool: Refactored lib/mody.py
--- lib/mody.py (original)
+++ lib/mody.py (refactored)
@@ -1,4 +1,4 @@
-from modx import does_something
+from .modx import does_something

 def loaded():
     string = does_something()
RefactoringTool: Files that need to be modified:
RefactoringTool: lib/modx.py
RefactoringTool: lib/mody.py

Мне пришлось модифицировать оператор импорта mody.py, чтобы исправить его

try:
    from modx import does_something
except ImportError:
    from .modx import does_something


def loaded():
    string = does_something()
    print(string)

Затем я снова запустил main.py и получил ожидаемый вывод

$ python main.py
I gave you this string.

Наконец, просто очистите его и сделайте его переносимым между 2 и 3.

from __future__ import absolute_import
from .modx import does_something

Ответ 4

Настройка PYTHONPATH также может помочь с этой проблемой.

Вот как это можно сделать на Windows

set PYTHONPATH=.

Ответ 5

Попробовал ваш пример

from . import config

получил следующую системную ошибку:
/usr/bin/python3.4 test.py
Traceback (последний вызов был последним):
  Файл "test.py", строка 1, в
    из. импортировать конфигурацию
SystemError: Родительский модуль '' не загружен, не может выполнить относительный импорт


Это будет работать для меня:

import config
print('debug=%s'%config.debug)

>>>debug=True

Протестировано с Python: 3.4.2 - PyCharm 2016.3.2


Кроме этого PyCharm предлагает вам импортировать это имя.
Вы должны нажать config, и появится значок справки. enter image description here

Ответ 6

Вы можете просто добавить следующий файл в ваш каталог тестов, и тогда python запустит его перед тестами

__init__.py file

import os
import sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

Ответ 7

Вы должны добавить путь модулей к PYTHONPATH:

export PYTHONPATH="${PYTHONPATH}:/path/to/your/module/"

Ответ 8

Этот пример работает на Python 3.6.

Я предлагаю перейти к Run -> Edit Configurations в PyCharm, удалив все записи там и попытаться снова запустить код через PyCharm.

Если это не сработает, проверьте интерпретатор проекта (Настройки → Переводчик проекта) и запустите настройки конфигурации по умолчанию (Запустить → Изменить конфигурации...).

Ответ 9

Объявите правильный список sys.path перед вызовом модуля:

import os, sys

#'/home/user/example/parent/child'
current_path = os.path.abspath('.')

#'/home/user/example/parent'
parent_path = os.path.dirname(current_path)

sys.path.append(parent_path)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'child.settings')

Ответ 10

У меня была аналогичная проблема. Поскольку ошибка говорит, что python не смог найти имя модуля, я догадался, что файл якобы отсутствует там, где он должен был быть.

  • Мой рабочий каталог: C:\Users\piyus >

  • В папке, где я сохранил мой модуль: C:\Users\piyus\Desktop\Python Stuff

Поэтому я переместил файл модуля в рабочий каталог, и он работал как шарм.

Как проверить, что ваш рабочий каталог:

import os
cwd = os.getcwd()
print(cwd)

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

Спасибо.