Kesalahan "Tidak dapat mengimpor" PyLint - cara mengatur PYTHONPATH?

165

Saya menjalankan PyLint dari dalam Wing IDE pada Windows. Saya memiliki sub-direktori (paket) di proyek saya dan di dalam paket saya mengimpor modul dari tingkat atas, yaitu.

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

Di dalam two.pysaya miliki import onedan ini berfungsi dengan baik pada saat runtime, karena direktori tingkat atas (dari yang myapp.pydijalankan) ada di jalur Python. Namun, ketika saya menjalankan PyLint di two.py itu memberi saya kesalahan:

F0401: Unable to import 'one'

Bagaimana cara saya memperbaikinya?

EMP
sumber

Jawaban:

145

Ada dua opsi yang saya ketahui.

Pertama, ubah PYTHONPATHvariabel lingkungan untuk memasukkan direktori di atas modul Anda.

Atau, edit ~/.pylintrcuntuk memasukkan direktori di atas modul Anda, seperti ini:

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

(Atau dalam versi pylint lainnya, init-hook mengharuskan Anda untuk mengubah [Umum] menjadi [MASTER])

Kedua opsi ini seharusnya bekerja.

Semoga itu bisa membantu.

Brian M. Hunt
sumber
8
Pylint hook ini saat ini merupakan cara terbaik dalam VScode karena PYTHONPATH belum didukung untuk itu dibangun dalam penggunaan linter.
Danny Staple
2
Saya memiliki masalah yang sama menggunakan MacVim dengan sintaksis. Bagaimana saya bisa mengkonfigurasi prosector untuk memperbaiki kesalahan impor?
Laurent
Posting blog terkait dengan beberapa detail lagi.
Christian Long
~/.pylintrcbekerja untuk saya di OSX, yang lain tidak berfungsi
Miquel
Tidak yakin mengapa hal ini bukan jawaban yang diterima - juga, layak disebut bagi mereka tersandung pada ini, yang Anda butuhkan untuk export PYTHONPATHsehingga pylintakan melihatnya (setidaknya, di bash / zsh)
Marco Massenzio
43

Solusi untuk mengubah jalur masuk init-hookadalah baik, tetapi saya tidak menyukai kenyataan bahwa saya harus menambahkan jalur absolut di sana, karena itu saya tidak dapat membagikan file pylintrc ini di antara para pengembang proyek. Solusi ini menggunakan jalur relatif ke file pylintrc berfungsi lebih baik untuk saya:

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

Catatan yang pylint.config.PYLINTRCjuga ada dan memiliki nilai yang sama dengan find_pylintrc().

alex_koval
sumber
1
Mengkonfirmasi bahwa ini benar-benar memasok solusi untuk kesalahan pylint E0611 dan E0401. Untuk pengguna VSCode: Penting bahwa folder yang dibuka adalah "folder root python", dan .pylintrc ada di folder itu.
np8
juga, pastikan tidak ada nama direktori modul Anda mulai dengan .(titik).
Saw-mon dan Natalie
2
jika Anda ingin menambahkan sub-folder tertentu (yaitu app), Anda dapat menggunakanfrom 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 adalah daftar.

2) Masalahnya kadang-kadang sys.path bukan virtualenv.path Anda dan Anda ingin menggunakan pylint di virtualenv Anda

3) Jadi seperti dikatakan, gunakan init-hook (perhatikan dalam 'dan "parsing pylint ketat)

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

atau

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

.. dan

pylint --rcfile /path/to/pylintrc /path/to/module.py
macm
sumber
8
Saya tampaknya telah memperbaiki ini dengan menginstal pylintke dalam virtualenv saya sesuai saran ini: plaidzooks.tumblr.com/post/36813101879
Matt
3
Ini berfungsi dengan baik, dan harus menjadi jawaban teratas. Jika Anda tidak memiliki set .pylintrc maka pastikan untuk melakukan quick pylint --generate-rcfile > .pylintrcdi folder home Anda.
reka18
26

Masalahnya dapat diselesaikan dengan mengkonfigurasi jalur pylint di bawah venv: $ cat .vscode / settings.json

{
    "python.pythonPath": "venv/bin/python",
    "python.linting.pylintPath": "venv/bin/pylint"
}
jeanerpp
sumber
2
Untuk Windows, itu { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } Hanya untuk kelengkapan.
Roy2511
Pertanyaannya jangan tanyakan editor ini.
Ivailo Bardarov
VSCode sekarang menunjukkan pesan ini: The setting "python.pythonPath" defined in your settings.json is now deprecated. Jika saya menghapus python.pythonPathbaris sepertinya masih berfungsi.
Jesse Aldridge
23

Apakah Anda memiliki __init__.pyfile kosong di kedua direktori untuk memberi tahu python bahwa direktori adalah modul?

Garis dasar ketika Anda tidak menjalankan dari dalam folder (yaitu mungkin dari pylint, meskipun saya belum pernah menggunakannya) adalah:

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

Ini adalah bagaimana interpreter python mengetahui modul tanpa referensi ke direktori saat ini, jadi jika pylint dijalankan dari jalur absolutnya sendiri, ia akan dapat diakses functions_etc.pysebagai topdir.functions_etcatau topdir.subdir.other_functions, asalkan topdirada pada PYTHONPATH.

UPDATE: Jika masalahnya bukan pada __init__.pyfile, mungkin hanya mencoba menyalin atau memindahkan modul Anda ke c:\Python26\Lib\site-packages- itu adalah tempat umum untuk meletakkan paket tambahan, dan pasti akan berada di pythonpath Anda. Jika Anda tahu cara melakukan tautan simbolik Windows atau yang setara (saya tidak!), Anda bisa melakukannya. Ada banyak opsi di sini: http://docs.python.org/install/index.html , termasuk opsi untuk menambahkan sys.path dengan direktori tingkat pengguna dari kode pengembangan Anda, tetapi dalam praktiknya saya biasanya hanya secara simbolis menghubungkan dir pengembangan lokal saya ke paket situs - menyalinnya memiliki efek yang sama.

lepas
sumber
1
Ya, saya punya __init__.pydi kedua direktori. Saya pikir masalahnya adalah bahwa direktori teratas TIDAK di PYTHONPATH ketika PyLint berjalan dan saya tidak yakin bagaimana cara memperbaikinya.
EMP
Symlink adalah ide yang bagus, tetapi hanya didukung dari Windows Vista dan seterusnya dan saya menjalankan XP. Saya kira saya bisa mencoba menghubungkannya ...
EMP
re hardlinking: Tidak, lebih baik Anda tidak melakukannya. Saya sudah bermain dengannya dan, meskipun pasti bekerja (dengan cara), itu tidak akan berfungsi seperti yang Anda harapkan.
shylent
Symlink bukanlah ide yang baik. Ini hanya memperbaiki masalah pada mesin Anda - ketika orang lain memeriksa proyek, itu akan rusak untuk mereka.
Jonathan Hartley
12

jawaban umum untuk pertanyaan ini saya temukan di halaman ini TOLONG BUKAN, SITUS BUGED

buat .pylintrcdan tambahkan

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

Saya tidak tahu cara kerjanya dengan WingIDE, tetapi untuk menggunakan PyLint dengan Geany, saya mengatur perintah eksternal saya ke:

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

di mana% f adalah nama file, dan% d adalah path. Semoga bermanfaat bagi seseorang :)

simon
sumber
4

Saya harus memperbarui PYTHONPATHvariabel sistem untuk menambahkan jalur App Engine saya. Dalam kasus saya, saya hanya perlu mengedit ~/.bashrcfile dan menambahkan baris berikut:

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

Sebenarnya, saya mencoba mengatur yang init-hookpertama tetapi ini tidak menyelesaikan masalah secara konsisten di basis kode saya (tidak yakin mengapa). Setelah saya menambahkannya ke jalur sistem (mungkin ide yang bagus secara umum) masalah saya hilang.

Brian Moeskau
sumber
3

Satu solusi yang baru saja saya temukan adalah untuk benar-benar hanya menjalankan PyLint untuk seluruh paket, daripada satu file. Entah bagaimana, ia berhasil menemukan modul yang diimpor kemudian.

EMP
sumber
Kedengarannya bagus; bagaimana?
Cees Timmerman
1
@CeesTimmerman Jalankan pylint ... dirdari folder induk. Ini __init__.pyharus ada di setiap subfolder dengan .pyfile.
yugr
3

Mencoba

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

Perhatikan bahwa dalam Python 3, sintaks untuk bagian dalam elseklausa akan menjadi

from .. import one

Setelah dipikir-pikir, ini mungkin tidak akan memperbaiki masalah spesifik Anda. Saya salah mengerti pertanyaan dan berpikir bahwa two.py dijalankan sebagai modul utama, tetapi bukan itu masalahnya. Dan mengingat perbedaan dalam cara Python 2.6 (tanpa mengimpor absolute_importdari __future__) dan Python 3.x menangani impor, Anda tidak perlu melakukan ini untuk Python 2.6, saya tidak berpikir.

Namun, jika Anda akhirnya beralih ke Python 3 dan berencana menggunakan modul sebagai modul paket dan juga skrip mandiri di dalam paket, mungkin ide yang bagus untuk menyimpan sesuatu seperti

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

dalam pikiran.

EDIT: Dan sekarang untuk solusi yang mungkin untuk masalah Anda yang sebenarnya. Jalankan PyLint dari direktori yang berisi onemodul Anda (mungkin melalui baris perintah), atau letakkan kode berikut di suatu tempat saat menjalankan PyLint:

import os

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

Pada dasarnya, sebagai alternatif untuk mengutak-atik PYTHONPATH, pastikan direktori kerja saat ini adalah direktori yang berisi one.pyketika Anda melakukan impor.

(Melihat jawaban Brian, Anda mungkin dapat menetapkan kode sebelumnya init_hook, tetapi jika Anda akan melakukan itu maka Anda bisa menambahkannya sys.path, yang sedikit lebih elegan daripada solusi saya.)

TUSUKAN
sumber
2

Kuncinya adalah menambahkan direktori proyek Anda sys.pathtanpa mempertimbangkan variabel env.

Untuk seseorang yang menggunakan VSCode, berikut ini adalah solusi satu baris untuk Anda jika ada direktori dasar proyek Anda:

[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)'

Biarkan saya jelaskan sedikit:

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): cari direktori dasar sesuai dengan file pengeditan

  • os.path.join(os.getcwd(), base_dir): tambahkan cwdke sys.pathuntuk memenuhi lingkungan baris perintah


FYI, ini .pylintrc saya:

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

chuyik
sumber
2

Saya memiliki masalah yang sama dan memperbaikinya dengan menginstal pylint di virtualenv saya dan kemudian menambahkan file .pylintrc ke direktori proyek saya dengan yang berikut dalam file:

[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
Nate
sumber
Saya harus mengkonfirmasi bahwa ini menghilangkan kesalahan pylint E0611, tetapi kesalahan E0401 tetap.
np8
1

Mungkin dengan menambahkan dir secara manual di dalam PYTHONPATH?

sys.path.append(dirname)
Mario Mikić
sumber
Hmm, tapi di mana Anda akan meletakkan kode itu? Di bagian atas setiap file? Saya kira itu akan berhasil, tapi itu cukup hack hanya untuk membuat PyLint bekerja.
EMP
@ Evgeny: Lihat jawaban yang baru-baru ini diposting oleh Brian M. Hunt.
JAB
Dan menambahkan ini di bagian atas setiap file tidak berfungsi karena suatu alasan - PyLint tampaknya puas untuk mengabaikan modifikasi apa pun pada sys.path yang dibuat dari dalam modul-modul yang sedang dipindai. Saya belum repot-repot untuk meneliti mengapa, ...
javawizard
1

Saya memiliki masalah yang sama dan karena saya tidak dapat menemukan jawaban, saya harap ini dapat membantu siapa saja dengan masalah yang sama.

Saya menggunakan flymake dengan epylint. Pada dasarnya yang saya lakukan adalah menambahkan dired-mode-hook yang memeriksa apakah direktori dired adalah direktori paket python. Jika itu saya tambahkan ke PYTHONPATH. Dalam kasus saya, saya menganggap direktori sebagai paket python jika berisi file bernama "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)

Semoga ini membantu.

pengguna2826500
sumber
1

Jika ada yang mencari cara untuk menjalankan pylint sebagai alat eksternal di PyCharm dan membuatnya bekerja dengan lingkungan virtual mereka (mengapa saya sampai pada pertanyaan ini), inilah cara saya menyelesaikannya:

  1. Di PyCharm> Preferensi> Alat> Alat Eksternal, Tambah atau Edit item untuk pylint.
  2. Dalam Pengaturan Alat pada dialog Edit Alat, tetapkan Program untuk menggunakan pylint dari direktori juru bahasa python: $PyInterpreterDirectory$/pylint
  3. Setel parameter Anda yang lain di bidang Parameter, seperti: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Setel direktori kerja Anda ke $FileDir$

Sekarang menggunakan pylint sebagai alat eksternal akan menjalankan pylint pada direktori apa pun yang telah Anda pilih menggunakan file konfigurasi umum dan menggunakan penerjemah apa pun yang dikonfigurasi untuk proyek Anda (yang mungkin adalah penerjemah virtualenv Anda).

tterry
sumber
1

Ini adalah pertanyaan lama tetapi tidak memiliki jawaban yang diterima, jadi saya akan menyarankan ini: ubah pernyataan impor dalam two.py untuk membaca:

from .. import one

Di lingkungan saya saat ini (Python 3.6, VSCode menggunakan pylint 2.3.1) ini menghapus pernyataan yang ditandai.

Mike C
sumber
1

Saya menemukan jawaban yang bagus . Edit pylintrc Anda dan tambahkan berikut ini di 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'))"
Devguru
sumber
1

Ketika Anda menginstal Python, Anda dapat mengatur path. Jika path sudah ditentukan maka yang dapat Anda lakukan adalah di dalam VS Code, tekan Ctrl + Shift + P dan ketik Python: Pilih Interpreter dan pilih versi terbaru dari Python. Ikuti tautan ini untuk informasi lebih lanjut, https://code.visualstudio.com/docs/python/environmentments

Nadeem
sumber
0

jika Anda menggunakan vscode, pastikan direktori paket Anda keluar dari direktori _pychache__.

Vikas Bhutani
sumber
Juga dengan kode VS, tampaknya ada potensi masalah dengan dot dalam nama folder: github.com/PyCQA/pylint/issues/2182
Eric Burel
0

Jika Anda menggunakan Cython di Linux, saya memutuskan untuk menghapus module.cpython-XXm-X-linux-gnu.sofile di direktori target proyek saya.

M. Andrade
sumber
0

cukup tambahkan kode ini dalam file .vscode / settings.json

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

Ini akan memberi tahu lokasi pylint (yang merupakan pemeriksa kesalahan untuk python)

pengguna3395246
sumber
-1

Halo saya bisa mengimpor paket dari direktori yang berbeda. Saya baru saja melakukan yang berikut: Catatan: Saya menggunakan VScode

Langkah-langkah untuk Membuat Paket Python Bekerja dengan paket Python sangat sederhana. Yang perlu Anda lakukan adalah:

Buat direktori dan berikan nama paket Anda. Masukkan kelas Anda di dalamnya. Buat file .py init di direktori

Misalnya: Anda memiliki folder bernama Kerangka kerja tempat Anda menyimpan semua kelas khusus di sana dan tugas Anda hanyalah membuat file .py init di dalam folder bernama Kerangka Kerja.

Dan saat mengimpor Anda perlu mengimpor dengan cara ini --->

dari basis impor Framework

sehingga kesalahan E0401 menghilang Framework adalah folder di mana Anda baru saja dibuat init .py dan base adalah modul kustom Anda yang harus Anda impor dan kerjakan semoga membantu !!!!

SUNEEL KAUSHIK S
sumber