Помилка 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-гак вимагає від вас змінити [General] на [MASTER])

Обидва ці варіанти повинні працювати.

Сподіваюся, що це допомагає.


8
Цей гачок пілінта на даний момент є найкращим способом у VScode, оскільки PYTHONPATH ще не підтримується, оскільки він вбудований у використання лінійки.
Danny Staple

2
У мене ж проблема з використанням MacVim із синтастикою. Як я можу налаштувати прожектор, щоб виправити помилку імпорту?
Лоран


~/.pylintrcпрацював у мене на OSX, інший не працював
Miquel

Не впевнений, чому це не прийнята відповідь - також, варто згадати тим, хто спотикається на цьому, що вам потрібно зробити export PYTHONPATHтак, щоб pylintпобачити це (принаймні, в bash / zsh)
Marco

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-гак (зверніть увагу на "і" синтаксичний розбір пілінта)

[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 файл в обох каталогах, щоб пітон знав, що dirs - це модулі?

Основний контур, коли ви не працюєте з папки (тобто, можливо, з pylint's, хоча я цього не використовував):

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- це звичайне місце для розміщення додаткових пакетів і обов'язково буде на вашому пітфонпаті. Якщо ви знаєте, як зробити символічні посилання Windows або їх аналогічні (я не знаю!), Ви можете зробити це замість цього. Тут є ще багато варіантів : http://docs.python.org/install/index.html , включаючи опцію додавання sys.path до каталогу користувачів на рівні вашого коду розробки, але на практиці я зазвичай просто символічно посилаю мій реєстр локальних розробок на сайти-пакети - їх копіювання має той же ефект.


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

Симпосилання є гарною ідеєю, але вона підтримується лише з Windows Vista і я працюю на XP. Я думаю, я міг би спробувати пов'язувати це ...
EMP

Повторне посилання: Ні, краще не роби цього. Я грав із цим і, хоча це, безумовно, працює (певним чином), воно не буде працювати, як ви очікували.
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 для всього пакету, а не для одного файлу. Якось йому вдається знайти імпортний модуль.


Звучить чудово; як?
Cees Timmerman

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

в пам'яті.

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що він робить, що трохи елегантніше, ніж моє рішення.)


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середовища оточення командного рядка


FYI, ось мій .pylintrc:

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


2

У мене була ця сама проблема і виправлено її, встановивши pylint у своєму virtualenv, а потім додавши .pylintrc файл до мого каталогу проектів із наступним файлом:

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

Я маю підтвердити, що це позбавляється від помилок у Pylint E0611, але помилки E0401 залишаються.
np8

1

Може, вручну додавши реж всередину ПІТОНПАТУ?

sys.path.append(dirname)

Хм, але де ти поставив би цей код? У верхній частині кожного файлу? Я гадаю, що це спрацювало б, але це досить хакер просто для того, щоб змусити PyLint працювати.
EMP

@ Євген: Дивіться відповідь, яку нещодавно опублікував Брайан М. Хант.
JAB

І додавання цього вгорі кожного файлу чомусь не працює - PyLint здається ідеальним вмістом ігнорувати будь-які модифікації sys.path, зроблені з модулів, які він сканує. Я не
намагався

1

У мене була така ж проблема, і оскільки я не міг знайти відповіді, сподіваюся, що це може допомогти будь-кому із подібною проблемою.

Я використовую мухомор з епілінтом. В основному те, що я зробив, було додати гачку в режимі, що перевіряється, чи перевіряється, чи перенесений каталог - це каталог пакунків 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> Налаштування> Інструменти> Зовнішні інструменти, додайте або відредагуйте елемент для pylint.
  2. У діалоговому вікні "Налаштування інструмента" у діалоговому вікні "Інструмент редагування" встановіть програму на використання пілінта з каталогу інтерпретатора 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, використовуючи пілінт 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.