Ошибка PyLint "Не удалось импортировать" - как установить PYTHONPATH?

Я запускаю 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'

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

Ответ 1

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

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

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

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

(или в другой версии pylint, ловушка инициализации требует, чтобы вы изменили [General] на [MASTER])

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

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

Ответ 2

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

Ответ 3

Решение об изменении пути в 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().

Ответ 4

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

Основной контур, когда вы не работаете из папки (т.е., может быть, из 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.

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

Ответ 5

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

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

Ответ 6

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

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

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

Ответ 7

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

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

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

Ответ 8

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

Ответ 9

Попробуйте

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

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

from .. import one

Забастовкa >

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

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

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

в виду.

EDIT: И теперь для возможного решения вашей реальной проблемы. Либо запустите 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, которое он делает, что немного более элегантно чем мое решение.)

Ответ 10

Ключ состоит в том, чтобы добавить каталог проекта в 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 для соответствия среде командной строки


FYI, здесь мой .pylintrc:

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

Ответ 11

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

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

Ответ 12

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

sys.path.append(dirname)

Ответ 13

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

Я использую flymake с эпилином. В основном то, что я сделал, это добавить привязку в режиме ожидания, которая проверяет, является ли устаревшая директория каталогом пакетов 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)

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

Ответ 14

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

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

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

Ответ 15

Я нашел хороший ответ от https://sam.hooke.me/note/2019/01/call-python-script-from-pylint-init-hook/ отредактируйте ваш 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'))"

Ответ 16

если вы используете vscode, убедитесь, что каталог вашего пакета находится вне каталога _pychache__.

Ответ 17

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

from .. import one

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

Ответ 18

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

Ответ 19

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

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

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

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

И при импорте вам нужно импортировать в этот fashion--->

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

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