PyLint «Невозможно импортировать» ошибка - как установить PYTHONPATH?


165

Я запускаю PyLint изнутри Wing IDE на Windows. У меня есть подкаталог (пакет) в моем проекте, и внутри пакета я импортирую модуль с верхнего уровня, т.е.

__init__.py
myapp.py
one.py
subdir\
    __init__.py
    two.py

Внутри у two.pyменя есть, import oneи это прекрасно работает во время выполнения, потому что каталог верхнего уровня (из которого myapp.pyзапускается) находится в пути Python. Однако, когда я запускаю PyLint на two.py, он выдает ошибку:

F0401: Unable to import 'one'

Как это исправить?

Ответы:


145

Есть два варианта, которые я знаю.

Во-первых, измените PYTHONPATHпеременную среды, чтобы она включала каталог над вашим модулем.

Или отредактируйте, ~/.pylintrcчтобы включить каталог над вашим модулем, например так:

[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'

(Или в другой версии pylint, init-hook требует от вас изменить [General] на [MASTER])

Оба эти варианта должны работать.

Надеюсь, это поможет.


8
Этот хобот pylint в настоящее время является лучшим способом в VScode, так как PYTHONPATH еще не поддерживается, поскольку он встроен в использование линтера.
Дэнни Стейпл

2
У меня та же проблема с использованием MacVim с синтетическим. Как я могу настроить prosector для исправления ошибки импорта?
Лоран

Связанное сообщение в блоге с несколькими дополнительными деталями.
Кристиан Лонг

~/.pylintrcработал для меня на OSX, другой не работал
Микель

Не уверен, почему это не принятый ответ - также стоит упомянуть для тех, кто спотыкается об этом, что вам нужно, чтобы export PYTHONPATHэто pylintувидели (по крайней мере, в bash / zsh)
Марко Массенцио

43

Решение по изменению пути init-hook- это хорошо, но мне не нравится тот факт, что мне пришлось добавить туда абсолютный путь, так как в результате я не могу поделиться этим файлом pylintrc среди разработчиков проекта. Это решение, использующее относительный путь к файлу pylintrc, работает лучше для меня:

[MASTER]
init-hook="from pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"

Обратите внимание, что pylint.config.PYLINTRCтакже существует и имеет то же значение, что и find_pylintrc().


1
Подтверждение того, что это действительно обеспечило решение для ошибок цилиндров E0611 и E0401. Для пользователей VSCode: важно, чтобы открытая папка была «корневой папкой python» и чтобы в ней находился файл .pylintrc.
NP8

также убедитесь, что ни одно из имен каталогов вашего модуля не начинается с .(точка).
и Натали

2
если вы хотите добавить определенную подпапку (то есть app), которую вы можете использоватьfrom pylint.config import find_pylintrc; import os, sys; sys.path.append(os.path.join(os.path.dirname(find_pylintrc()), 'app'))
chachan

27

1) sys.path - это список.

2) Иногда проблема в том, что sys.path не является вашим virtualenv.path, и вы хотите использовать pylint в вашем virtualenv.

3) Как и сказано, используйте init-hook (обратите внимание на 'и "синтаксический анализ pylint)

[Master]
init-hook='sys.path = ["/path/myapps/bin/", "/path/to/myapps/lib/python3.3/site-packages/", ... many paths here])'

или

[Master]
init-hook='sys.path = list(); sys.path.append("/path/to/foo")'

.. и

pylint --rcfile /path/to/pylintrc /path/to/module.py

8
Я, кажется, исправил это, установив pylintв свой virtualenv согласно этому совету: plaidzooks.tumblr.com/post/36813101879
Мэтт

3
Это прекрасно работает, и должен быть лучшим ответом. Если у вас нет установленного .pylintrc, то просто сделайте быстрое pylint --generate-rcfile > .pylintrcв вашей домашней папке.
reka18

26

Проблема может быть решена путем настройки пути pylint под venv: $ cat .vscode / settings.json

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}

2
Для Windows это { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } просто для полноты.
Roy2511

Вопрос не задавайте для этого редактора.
Ивайло Бардаров

VSCode теперь показывает это сообщение: The setting "python.pythonPath" defined in your settings.json is now deprecated. если я удаляю python.pythonPathстроку, она все еще работает.
Джесси Олдридж

23

У вас есть пустой __init__.pyфайл в обоих каталогах, чтобы python знал, что каталоги являются модулями?

Основная схема, когда вы не запускаете из папки (то есть, возможно, из Pylint, хотя я не использовал это):

topdir\
  __init__.py
  functions_etc.py
  subdir\
    __init__.py
    other_functions.py

Это то, как интерпретатор Python узнает о модуле без ссылки на текущий каталог, поэтому, если Pylint работает по своему собственному абсолютному пути, он сможет получить доступ functions_etc.pyкак topdir.functions_etcили topdir.subdir.other_functions, если он topdirнаходится в PYTHONPATH.

ОБНОВЛЕНИЕ: Если проблема не в __init__.pyфайле, возможно просто попробуйте скопировать или переместить ваш модуль в c:\Python26\Lib\site-packages- это обычное место для размещения дополнительных пакетов, и он обязательно будет в вашем pythonpath. Если вы знаете, как создавать символические ссылки Windows или аналогичные (я не знаю!), Вы можете сделать это вместо этого. Здесь есть еще много вариантов : http://docs.python.org/install/index.html , включая возможность добавления sys.path к каталогу пользовательского уровня вашего кода разработки, но на практике я обычно просто символически связываю мой локальный каталог разработки для пакетов сайта - копирование его имеет тот же эффект.


1
Да, у меня есть __init__.pyв обоих каталогах. Я думаю, что проблема в том, что верхний каталог НЕ находится в PYTHONPATH при запуске PyLint, и я не уверен, как это исправить.
EMP

Символическая ссылка - хорошая идея, но она поддерживается только в Windows Vista и далее, и я использую XP. Я полагаю, я мог бы попытаться жестко связать это ...
EMP

re hardlinking: Нет, лучше не делай этого. Я играл с ним, и, хотя он, безусловно, работает (в некотором смысле), он не будет работать, как вы ожидаете.
Shylent

Симлинки не очень хорошая идея. Это только устраняет проблему на вашей машине - когда кто-то еще проверяет проект, он будет сломан для них.
Джонатан Хартли


5

Я не знаю, как это работает с WingIDE, но для использования PyLint с Geany я установил свою внешнюю команду на:

PYTHONPATH=${PYTHONPATH}:$(dirname %d) pylint --output-format=parseable --reports=n "%f"

где% f - имя файла, а% d - путь. Может быть кому-то пригодится :)


4

Мне пришлось обновить системную PYTHONPATHпеременную, чтобы добавить мой путь к App Engine. В моем случае мне просто нужно было отредактировать мой ~/.bashrcфайл и добавить следующую строку:

export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder

На самом деле, я попытался установить init-hookпервый, но это не помогло решить проблему во всей моей кодовой базе (не знаю почему). Как только я добавил его в системный путь (вероятно, хорошая идея в целом), мои проблемы исчезли.


3

Один из обходных путей, который я только что обнаружил, - это просто запустить PyLint для всего пакета, а не для одного файла. Каким-то образом удается найти импортированный модуль.


Звучит здорово; как?
Сис Тиммерман

1
@CeesTimmerman Запустить pylint ... dirиз родительской папки. Это требует __init__.pyприсутствия в каждой подпапке с .pyфайлами.
Югр

3

Пытаться

if __name__ == '__main__':
    from [whatever the name of your package is] import one
else:
    import one

Обратите внимание, что в Python 3 синтаксис для части в else предложении будет

from .. import one

Если подумать, это, вероятно, не решит вашу конкретную проблему. Я неправильно понял вопрос и подумал, что two.py запускается как основной модуль, но это не так. И учитывая различия в способе Python 2.6 (без импорта absolute_importиз__future__ ) и Python 3.x, в любом случае вам не понадобится делать это для Python 2.6, я не думаю.

Тем не менее, если вы в конечном итоге переключитесь на Python 3 и планируете использовать модуль как пакетный модуль и как отдельный скрипт внутри пакета, возможно, будет хорошей идеей сохранить что-то вроде

if __name__ == '__main__':
    from [whatever the name of your package is] import one   # assuming the package is in the current working directory or a subdirectory of PYTHONPATH
else:
    from .. import one

в уме.

РЕДАКТИРОВАТЬ: И теперь для возможного решения вашей актуальной проблемы. Либо запустите PyLint из каталога, содержащего ваш oneмодуль (возможно, из командной строки), либо поместите следующий код где-нибудь при запуске PyLint:

import os

olddir = os.getcwd()
os.chdir([path_of_directory_containing_module_one])
import one
os.chdir(olddir)

В основном, в качестве альтернативы возни с PYTHONPATH, просто убедитесь, что текущий рабочий каталог - это каталог, содержащий one.py при выполнении импорта.

(Глядя на ответ Брайана, вы, вероятно, могли бы присвоить предыдущий код init_hook, но если вы собираетесь это сделать, то можете просто добавить к нему sys.pathто, что он делает, что несколько элегантнее, чем мое решение.)


2

Ключ должен добавить каталог вашего проекта в sys.path без учета переменной env.

Для тех, кто использует VSCode, вот решение для одной строки, если есть базовый каталог вашего проекта:

[MASTER]
init-hook='base_dir="my_spider"; import sys,os,re; _re=re.search(r".+\/" + base_dir, os.getcwd()); project_dir = _re.group() if _re else os.path.join(os.getcwd(), base_dir); sys.path.append(project_dir)'

Позвольте мне объяснить это немного:

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): найти базовый каталог в соответствии с файлом редактирования

  • os.path.join(os.getcwd(), base_dir): добавить, cwdчтобы sys.pathсоответствовать среде командной строки


К вашему сведению, вот мой .pylintrc:

https://gist.github.com/chuyik/f0ffc41a6948b6c87c7160151ffe8c2f


2

У меня была та же проблема, и я исправил ее, установив pylint в моем virtualenv, а затем добавив файл .pylintrc в каталог моего проекта, добавив в него следующее:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'

Я должен подтвердить, что это избавляет от ошибок пилона E0611, но ошибки E0401 остаются.
NP8

1

Может быть, вручную добавив dir в PYTHONPATH?

sys.path.append(dirname)

Хм, а где бы вы положили этот код? В верхней части каждого файла? Я полагаю, это сработает, но это просто взломать, чтобы заставить работать PyLint.
EMP

@ Евгений: Смотрите ответ, который недавно опубликовал Брайан М. Хант.
JAB

И добавление этого в начало каждого файла по какой-то причине не работает - PyLint, кажется, вполне доволен тем, что игнорирует любые изменения в sys.path, сделанные из модулей, которые он сканирует. Я не удосужился исследовать, почему, хотя ...
javawizard

1

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

Я использую мухи с эпилинтом. По сути, я добавил хук dired-mode, который проверял, является ли каталог dired каталогом пакета python. Если это так, я добавляю его в PYTHONPATH. В моем случае я считаю каталог пакетом Python, если он содержит файл с именем «setup.py».

;;;;;;;;;;;;;;;;;
;; PYTHON PATH ;;
;;;;;;;;;;;;;;;;;

(defun python-expand-path ()
  "Append a directory to the PYTHONPATH."
  (interactive
   (let ((string (read-directory-name 
          "Python package directory: " 
          nil 
          'my-history)))
     (setenv "PYTHONPATH" (concat (expand-file-name string)
                  (getenv ":PYTHONPATH"))))))

(defun pythonpath-dired-mode-hook ()
  (let ((setup_py (concat default-directory "setup.py"))
    (directory (expand-file-name default-directory)))
    ;;   (if (file-exists-p setup_py)
    (if (is-python-package-directory directory)
    (let ((pythonpath (concat (getenv "PYTHONPATH") ":" 
                  (expand-file-name directory))))
      (setenv "PYTHONPATH" pythonpath)
      (message (concat "PYTHONPATH=" (getenv "PYTHONPATH")))))))

(defun is-python-package-directory (directory)
  (let ((setup_py (concat directory "setup.py")))
    (file-exists-p setup_py)))

(add-hook 'dired-mode-hook 'pythonpath-dired-mode-hook)

Надеюсь это поможет.


1

Если кто-то ищет способ запустить Pylint как внешний инструмент в PyCharm и заставить его работать со своими виртуальными средами (почему я пришел к этому вопросу), вот как я решил это:

  1. В PyCharm> «Настройки»> «Инструменты»> «Внешние инструменты» добавьте или измените элемент для столбца.
  2. В настройках инструмента диалогового окна «Редактировать инструмент» задайте для программы использование pylint из каталога интерпретатора python: $PyInterpreterDirectory$/pylint
  3. Установите другие параметры в поле «Параметры», например: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Установите ваш рабочий каталог на $FileDir$

Теперь использование pylint в качестве внешнего инструмента будет запускать pylint в любом каталоге, который вы выбрали, используя общий файл конфигурации, и использовать любой интерпретатор, настроенный для вашего проекта (который, вероятно, является вашим интерпретатором virtualenv).


1

Это старый вопрос, но нет принятого ответа, поэтому я предлагаю: измените оператор импорта в two.py, чтобы он читался так:

from .. import one

В моей текущей среде (Python 3.6, VSCode с использованием pylint 2.3.1) это очищает помеченный оператор.


1

Я нашел хороший ответ . Отредактируйте ваш pylintrc и добавьте следующее в master

init-hook="import imp, os; from pylint.config import find_pylintrc; imp.load_source('import_hook', os.path.join(os.path.dirname(find_pylintrc()), 'import_hook.py'))"

1

Когда вы устанавливаете Python, вы можете настроить путь. Если путь уже определен, то, что вы можете сделать, находится в VS Code, нажмите Ctrl + Shift + P и введите Python: выберите Interpreter и выберите обновленную версию Python. Перейдите по этой ссылке для получения дополнительной информации, https://code.visualstudio.com/docs/python/environments



0

Если вы используете Cython в Linux, я решил удалить module.cpython-XXm-X-linux-gnu.soфайлы из целевой директории моего проекта.


0

просто добавьте этот код в файл .vscode / settings.json

, "python.linting.pylintPath": "venv / bin / pylint"

Это сообщит местоположение pylint (который является средством проверки ошибок для python)


-1

Здравствуйте, я смог импортировать пакеты из другого каталога. Я просто сделал следующее: Примечание: я использую VScode

Шаги для создания пакета Python Работать с пакетами Python действительно просто. Все, что вам нужно сделать, это:

Создайте каталог и дайте ему имя вашего пакета. Поместите свои классы в это. Создайте файл init .py в каталоге

Например: у вас есть папка с именем Framework, в которой вы храните все пользовательские классы, и ваша задача - просто создать файл init .py внутри папки с именем Framework.

И при импорте нужно импортировать таким образом --->

из базы импорта Framework

ошибка E0401 исчезает. Framework - это папка, в которой вы только что создали init .py, а base - ваш пользовательский модуль, в который вы должны импортировать и работать над ним. Надеюсь, это поможет !!!!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.