WedX - журнал о программировании и компьютерных науках

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

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

  1. test.py
  2. config.py

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

config.py

debug = True

test.py

import config
print (config.debug)

Еще у меня есть __init__.py

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

ModuleNotFoundError: No module named 'config'

Я знаю, что соглашение py3 должно использовать абсолютный импорт:

from . import config

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

ImportError: cannot import name 'config'

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


  • Я не могу воспроизвести ошибку, как выполнить этот код? 05.05.2017
  • Я выполняю test.py через pyCharm с Python 3.6. У вас все нормально? 05.05.2017
  • Я выполняю его в режиме ожидания, который поставляется с python, а также как python test.py, и он отлично работает. У меня нет pyCharm, но, возможно, это плохая конфигурация pyCharm, которая вызывает проблему. 05.05.2017
  • Очень странно. Я использую WinPython - просто скачайте vanilla Python 3.6 с python.org, и он отлично работает. Никогда не думал проверять переводчик! Спасибо! 05.05.2017
  • Я предполагаю, что с PYTHONPATH происходит что-то странное. Проверьте настройки IDE и / или системные переменные среды. 06.05.2017
  • У меня точно такая же проблема. Это не пихарм! Это python3. Он работает в python2, но при использовании python3 вы видите эту ошибку! очень расстраивает. 08.08.2017
  • sys.path.append (r'C: /.../ LastFolder ') работает постоянно 10.08.2018

Ответы:


1

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 файлы больше не нужны.

09.05.2017
  • Могу ли я что-то сделать, чтобы абсолютный импорт всегда работал? Мол, позвонить sys.path.append('/some/path/my_module') внутри /some/path/my_module/__init__.py? 07.12.2017
  • @JamesT. Да, довольно часто можно изменять sys.path во время выполнения (github.com/). Вы также можете установить переменную среды PYTHONPATH. 08.12.2017
  • если вы придерживаетесь Python 3, __init__.py файлы больше не нужны. Интересно. Вы можете остановиться на этом? У меня создалось впечатление, что механизм разрешения пакетов не сильно изменился между 2 и 3. 07.05.2019
  • если вы придерживаетесь Python 3, вам больше не нужны __init__.py файлы. И наоборот, можете ли вы описать вещи, если мы хотим, чтобы пакет работал и в 2, и в 3? И посмотрите ужасно устаревший для чего __init__.py? от 2009 года и его ответ, получивший наибольшее количество голосов Это часть пакета. Нам нужно начать подчеркивать различие обычный пакет [старый, до 3.3] и namespace package [3.3+] везде и часто. 08.05.2019
  • Извините за спам в разделе комментариев, но ... чувак, большое спасибо за ваш ответ @Igonato! 20.09.2020
  • Спасибо за ответ. Мне интересно, эквивалентен ли в main.py из ryan import test import ryan.test (игнорировать различие префикса пространства имен, т.е. в первом мы можем получить доступ через test, а во втором мы должны получить доступ через ryan.test)? Собираются ли эти двое импортировать один и тот же набор переменных, определенных в пространстве имен test, и являются ли они абсолютным импортом? 14.06.2021

  • 2

    Я понял. Очень неприятно, особенно если исходить из 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
    
    07.08.2017
  • Стоит отметить, что процедура загрузки try/except - это реальный ингредиент, который здесь работает (так как некоторым людям нужно будет использовать try:scripts.modx и except: modx), и именно она решила эту проблему для меня. 02.03.2020
  • Попробуйте / кроме импорта некрасиво. Хотел бы я найти лучшее решение. 10.08.2020
  • Вы должны добавить. модулю, независимо от того, является он относительным или абсолютным Это не совсем точно. Если вы используете точку, это становится относительным импортом. 13.09.2020
  • большое спасибо! эта точка (.) была для меня актуальной проблемой =) 14.06.2021

  • 3

    Вы должны добавить путь своего проекта к PYTHONPATH и обязательно использовать абсолютный импорт.


    Для UNIX (Linux, OSX, ...)

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

    Для Windows

    set PYTHONPATH=%PYTHONPATH%;C:\path\to\your\project\
    

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

    Предполагая, что у нас есть следующая структура проекта,

    └── myproject
        ├── mypackage
        │   ├── a.py
        └── anotherpackage
            ├── b.py
            ├── c.py
            └── mysubpackage
                └── d.py
    

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

    # in module a.py
    import anotherpackage.mysubpackage.d
    
    # in module b
    import anotherpackage.c
    import mypackage.a
    

    Более подробное объяснение см. В статье Как исправить ModuleNotFoundError и ImportError < / а>

    23.07.2019
  • Огромное спасибо @Giorgos! Это особенно верно, когда вы пытаетесь установить корневой каталог в образе докера. 08.08.2019

  • 4

    Настройка PYTHONPATH также может помочь в решении этой проблемы.

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

    set PYTHONPATH=.

    02.02.2018
  • установка PYTHONPATH в основной каталог кода решила проблему для меня! 22.05.2018
  • Также работает в Linux. экспорт PYTHONPATH =. 03.03.2020

  • 5

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

    __init__.py file
    
    import os
    import sys
    sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
    
    22.04.2019
  • Это именно то, что я искал. Спасибо, что поделились этим ответом !!! 10.06.2019
  • Выполнение чего-то подобного приводит к ошибке линтера (pylint3). Ошибка похожа на эту. filename.py:12:0: C0413: Импорт import abc.def.ghi.file_util, поскольку file_util должен быть размещен в верхней части модуля (неправильная позиция импорта) 06.02.2020
  • Превосходно. Это содержимое файла __init__ работает в Python 3.6.6. 31.01.2021


  • 7

    Установите переменную среды PYTHONPATH в корневом каталоге проекта.

    Учитывая UNIX-подобный:

    export PYTHONPATH=.
    
    17.02.2020

    8

    Объявите правильный список 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')
    
    09.04.2019

    9

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

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

    Если это не сработает, проверьте интерпретатор вашего проекта (Настройки -> Интерпретатор проекта) и запустите настройки конфигурации по умолчанию (Выполнить -> Изменить конфигурации ...).

    11.05.2017

    10

    Пытаться

    from . import config
    

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

    18.05.2020

    11

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

    12.05.2017
  • Хм, мне неприятно это говорить, но со мной случилось то же самое. Среда воссоздания устраняет проблему. В моем случае я получал эту ошибку при запуске тестов. В той же среде сработала попытка импортировать тот же модуль. Среда воссоздания исправила их все (тот же Python версии 3.6) 01.08.2017
  • В разных IDE есть разные способы обработки пути, особенно для исходных файлов проекта (представлений, модулей, шаблонов и т. Д.). Если ваш проект правильно структурирован и закодирован, он должен работать со всеми (стандартными) IDE. Наличие проблем с популярными IDE, такими как WinPython, означает, что проблема действительно связана с вашим проектом. Как упоминалось выше, проблема в том, что вам нужно добавить файл. в модуль пользователем3159377, который должен быть принятым ответом. 12.12.2018

  • 12

    Если вы используете python 3+, попробуйте добавить строки ниже

    import os, sys
    dir_path = os.path.dirname(os.path.realpath(__file__))
    parent_dir_path = os.path.abspath(os.path.join(dir_path, os.pardir))
    sys.path.insert(0, parent_dir_path)
    
    24.05.2020

    13

    Для меня сработало простое добавление текущего каталога.

    Используя следующую структуру:

    └── myproject
        ├── a.py
        └── b.py
    

    a.py:

    from b import some_object
    # returns ModuleNotFound error
    
    from myproject.b import some_object
    # works
    
    10.12.2020
    Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]