PyLint không thể nhập lỗi lỗi - làm cách nào để thiết lập PYTHONPATH?


164

Tôi đang chạy PyLint từ bên trong Wing IDE trên Windows. Tôi có một thư mục con (gói) trong dự án của mình và bên trong gói tôi nhập một mô-đun từ cấp cao nhất, tức là.

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

Bên trong two.pytôi có import onevà điều này hoạt động tốt trong thời gian chạy, bởi vì thư mục cấp cao nhất (từ đó myapp.pyđược chạy) nằm trong đường dẫn Python. Tuy nhiên, khi tôi chạy PyLint trên Two.py, nó sẽ báo lỗi:

F0401: Unable to import 'one'

Làm thế nào để tôi sửa lỗi này?

Câu trả lời:


144

Có hai lựa chọn tôi biết.

Một, thay đổi PYTHONPATHbiến môi trường để bao gồm thư mục phía trên mô-đun của bạn.

Hoặc, chỉnh sửa ~/.pylintrcđể bao gồm thư mục phía trên mô-đun của bạn, như thế này:

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

(Hoặc trong phiên bản khác của pylint, init-hook yêu cầu bạn thay đổi [Chung] thành [MASTER])

Cả hai tùy chọn này nên hoạt động.

Mong rằng sẽ giúp.


8
Móc pylint này hiện là cách tốt nhất trong VScode vì PYTHONPATH chưa được hỗ trợ cho việc sử dụng linter được tích hợp sẵn.
Daniel Staple

2
Tôi có cùng một vấn đề khi sử dụng MacVim với cú pháp. Làm cách nào để định cấu hình prosector để sửa lỗi nhập?
Laurent


~/.pylintrclàm việc cho tôi trên OSX, cái khác không hoạt động
Miquel

Bạn không chắc chắn lý do tại sao đây không phải là câu trả lời được chấp nhận - cũng có, đáng nói cho những người ngại về vấn đề này, mà bạn cần phải export PYTHONPATHđể pylintsẽ nhìn thấy nó (ít nhất, trong bash / zsh)
Marco Massenzio

41

Giải pháp thay đổi đường dẫn init-hooklà tốt, nhưng tôi không thích thực tế là tôi phải thêm đường dẫn tuyệt đối vào đó, do đó tôi không thể chia sẻ tệp pylintrc này giữa các nhà phát triển dự án. Giải pháp này sử dụng đường dẫn tương đối đến tệp pylintrc hoạt động tốt hơn đối với tôi:

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

Lưu ý rằng pylint.config.PYLINTRCcũng tồn tại và có cùng giá trị như find_pylintrc().


1
Xác nhận rằng điều này thực sự đã cung cấp giải pháp cho các lỗi pylint E0611 và E0401. Đối với người dùng VSCode: Điều quan trọng là thư mục đã mở là "thư mục gốc python" và .pylintrc nằm trong thư mục đó.
np8

đồng thời, đảm bảo không có tên thư mục mô-đun nào của bạn bắt đầu bằng .(dấu chấm).
Saw-mon và Natalie

2
nếu bạn muốn thêm một thư mục con cụ thể (nghĩa là app) bạn có thể sử dụngfrom 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 là một danh sách.

2) Vấn đề đôi khi là sys.path không phải là virtualenv.path của bạn và bạn muốn sử dụng pylint trong virtualenv của mình

3) Như đã nói, hãy sử dụng init-hook (chú ý trong 'và "phân tích cú pháp là nghiêm ngặt)

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

hoặc là

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

.. và

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

8
Tôi dường như đã sửa lỗi này bằng cách cài đặt pylintvào virtualenv của mình theo lời khuyên này: plaidzooks.tumblr.com/post/36813101879
Matt

3
Điều này làm việc tuyệt vời, và nên là câu trả lời hàng đầu. Nếu bạn không có bộ .pylintrc thì chỉ cần đảm bảo thực hiện nhanh pylint --generate-rcfile > .pylintrctrong thư mục nhà của bạn.
reka18

26

Vấn đề có thể được giải quyết bằng cách định cấu hình đường dẫn pylint trong venv: $ cat .vscode / settings.json

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

2
Đối với Windows, đó chỉ là sự { "python.pythonPath": "${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath": "${workspaceFolder}\\.venv\\Scripts\\pylint.exe" } hoàn chỉnh.
Roy2511

Câu hỏi không yêu cầu biên tập viên này.
Ivailo Bardarov

VSCode hiện hiển thị thông báo này: The setting "python.pythonPath" defined in your settings.json is now deprecated. Nếu tôi xóa python.pythonPathdòng thì nó dường như vẫn hoạt động.
Jesse Aldridge

23

Bạn có một __init__.pytập tin trống trong cả hai thư mục để cho python biết rằng các thư mục là các mô-đun không?

Phác thảo cơ bản khi bạn không chạy từ trong thư mục (có thể là từ pylint, mặc dù tôi chưa sử dụng nó) là:

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

Đây là cách trình thông dịch python nhận biết mô-đun mà không cần tham chiếu đến thư mục hiện tại, vì vậy nếu pylint đang chạy từ đường dẫn tuyệt đối của chính nó, nó sẽ có thể truy cập functions_etc.pynhư topdir.functions_etchoặc topdir.subdir.other_functions, được cung cấp topdirtrên PYTHONPATH.

CẬP NHẬT: Nếu vấn đề không phải là __init__.pytệp, có thể chỉ cần thử sao chép hoặc di chuyển mô-đun của bạn sang c:\Python26\Lib\site-packages- đó là nơi phổ biến để đặt các gói bổ sung và chắc chắn sẽ nằm trên pythonpath của bạn. Nếu bạn biết cách thực hiện các liên kết tượng trưng của Windows hoặc tương đương (tôi không!), Bạn có thể làm điều đó thay vào đó. Có nhiều tùy chọn khác ở đây: http://docs.python.org/install/index.html , bao gồm tùy chọn nối thêm sys.path với thư mục cấp người dùng của mã phát triển của bạn, nhưng thực tế tôi thường chỉ liên kết một cách tượng trưng thư mục phát triển địa phương của tôi đến các gói trang web - sao chép nó cũng có tác dụng tương tự.


1
Vâng, tôi có __init__.pytrong cả hai thư mục. Tôi nghĩ vấn đề là thư mục hàng đầu KHÔNG có trong PYTHONPATH khi PyLint chạy và tôi không biết cách khắc phục điều đó.
EMP

Symlink là một ý tưởng hay, nhưng nó chỉ được hỗ trợ từ Windows Vista trở đi và tôi đang chạy XP. Tôi cho rằng tôi có thể thử liên kết nó một cách khó khăn ...
EMP

re hardlinking: Không, tốt hơn hết bạn đừng làm điều đó. Tôi đã chơi với nó và, trong khi nó chắc chắn hoạt động (theo một cách nào đó), nó sẽ không hoạt động như bạn mong đợi.
shylent

Symlinks không phải là một ý tưởng tốt. Điều này chỉ khắc phục sự cố trên máy của bạn - khi người khác kiểm tra dự án, nó sẽ bị hỏng đối với họ.
Jonathan Hartley


5

Tôi không biết nó hoạt động như thế nào với WingIDE, nhưng để sử dụng PyLint với Geany, tôi đặt lệnh bên ngoài của mình thành:

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

Trong đó% f là tên tệp và% d là đường dẫn. Có thể hữu ích cho ai đó :)


4

Tôi đã phải cập nhật PYTHONPATHbiến hệ thống để thêm đường dẫn Máy ứng dụng của mình. Trong trường hợp của tôi, tôi chỉ cần chỉnh sửa ~/.bashrctệp của mình và thêm dòng sau:

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

Trên thực tế, tôi đã thử đặt cài đặt init-hookđầu tiên nhưng điều này không giải quyết được vấn đề một cách nhất quán trên cơ sở mã của tôi (không biết tại sao). Khi tôi thêm nó vào đường dẫn hệ thống (có thể là một ý tưởng tốt nói chung), các vấn đề của tôi đã biến mất.


3

Một cách giải quyết khác mà tôi chỉ phát hiện ra là thực sự chỉ chạy PyLint cho toàn bộ gói, thay vì một tệp duy nhất. Bằng cách nào đó, nó quản lý để tìm mô-đun nhập khẩu sau đó.


Âm thanh tuyệt vời; làm sao?
Cees Timmerman

1
@CeesTimmerman Chạy pylint ... dirtừ thư mục mẹ. Điều này đòi hỏi __init__.pyphải có mặt trong mỗi thư mục con với .pycác tệp.
yugr

3

Thử

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

Lưu ý rằng trong Python 3, cú pháp của phần trong elsemệnh đề sẽ là

from .. import one

Suy nghĩ thứ hai, điều này có lẽ sẽ không khắc phục được vấn đề cụ thể của bạn. Tôi đã hiểu nhầm câu hỏi và nghĩ rằng Two.py đang được chạy như là mô-đun chính, nhưng đó không phải là trường hợp. Và xem xét sự khác biệt trong cách Python 2.6 (không nhập absolute_importtừ __future__) và Python 3.x xử lý nhập, dù sao bạn cũng không cần phải làm điều này với Python 2.6.

Tuy nhiên, nếu cuối cùng bạn chuyển sang Python 3 và dự định sử dụng một mô-đun vừa là mô-đun gói vừa là tập lệnh độc lập bên trong gói, thì có thể nên giữ một cái gì đó như

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

trong tâm trí.

EDIT: Và bây giờ cho một giải pháp có thể cho vấn đề thực tế của bạn. Chạy PyLint từ thư mục chứa onemô-đun của bạn (có thể thông qua dòng lệnh) hoặc đặt mã sau đây ở đâu đó khi chạy PyLint:

import os

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

Về cơ bản, thay thế cho việc thay đổi bằng PYTHONPATH, chỉ cần đảm bảo thư mục làm việc hiện tại là thư mục chứa one.pykhi bạn thực hiện nhập.

(Nhìn vào câu trả lời của Brian, có lẽ bạn có thể gán mã trước đó init_hook, nhưng nếu bạn đang đi để làm điều đó thì bạn chỉ có thể làm các phụ thêm để sys.pathmà anh ấy làm, đó là hơi hơn tao nhã hơn giải pháp của tôi.)


2

Điều quan trọng là thêm thư mục dự án của bạn vào sys.pathmà không xem xét về biến env.

Đối với ai đó sử dụng VSCode, đây là giải pháp một dòng cho bạn nếu có thư mục cơ sở của dự án của bạn:

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

Hãy để tôi giải thích một chút:

  • re.search(r".+\/" + base_dir, os.getcwd()).group(): tìm thư mục cơ sở theo tệp chỉnh sửa

  • os.path.join(os.getcwd(), base_dir): thêm cwdvào sys.pathđể đáp ứng môi trường dòng lệnh


FYI, đây là .pylintrc của tôi:

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


2

Tôi đã gặp vấn đề tương tự và khắc phục nó bằng cách cài đặt pylint trong virtualenv của tôi và sau đó thêm tệp .pylintrc vào thư mục dự án của tôi với tệp sau:

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

Tôi phải xác nhận rằng điều này được loại bỏ các lỗi pylint E0611, nhưng các lỗi E0401 vẫn còn.
np8

1

Có thể bằng cách nối thủ công các dir bên trong PYTHONPATH?

sys.path.append(dirname)

Hmm, nhưng bạn sẽ đặt mã đó ở đâu? Ở đầu mỗi tập tin? Tôi cho rằng nó sẽ hoạt động, nhưng nó khá là hack chỉ để PyLint hoạt động.
EMP

@Evgeny: Xem câu trả lời mà Brian M. Hunt mới đăng.
JAB

Và việc thêm phần này vào đầu mỗi tệp không hoạt động vì một số lý do - PyLint dường như hoàn toàn hài lòng khi bỏ qua mọi sửa đổi đối với sys.path được thực hiện từ bên trong các mô-đun mà nó đang quét. Tôi không bận tâm nghiên cứu tại sao, mặc dù ...
javawizard

1

Tôi đã có cùng một vấn đề và vì tôi không thể tìm thấy câu trả lời, tôi hy vọng điều này có thể giúp bất cứ ai có vấn đề tương tự.

Tôi sử dụng flymake với epylint. Về cơ bản những gì tôi đã làm là thêm một dired-mode-hook để kiểm tra xem thư mục dired có phải là thư mục gói python không. Nếu là tôi thêm nó vào PYTHONPATH. Trong trường hợp của tôi, tôi coi một thư mục là một gói python nếu nó chứa một tệp có tên là "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)

Hi vọng điêu nay co ich.


1

Trong trường hợp bất kỳ ai đang tìm cách chạy pylint như một công cụ bên ngoài trong PyCharm và để nó hoạt động với môi trường ảo của họ (tại sao tôi lại đến câu hỏi này), đây là cách tôi giải quyết nó:

  1. Trong PyCharm> Tùy chọn> Công cụ> Công cụ bên ngoài, Thêm hoặc Chỉnh sửa một mục cho pylint.
  2. Trong hộp thoại Cài đặt công cụ của hộp thoại Công cụ chỉnh sửa, đặt Chương trình để sử dụng pylint từ thư mục trình thông dịch python: $PyInterpreterDirectory$/pylint
  3. Đặt các tham số khác của bạn trong trường Tham số, như: --rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. Đặt thư mục làm việc của bạn thành $FileDir$

Bây giờ, sử dụng pylint làm công cụ bên ngoài sẽ chạy pylint trên bất kỳ thư mục nào bạn đã chọn bằng tệp cấu hình chung và sử dụng bất kỳ trình thông dịch nào được cấu hình cho dự án của bạn (có lẽ là trình thông dịch virtualenv của bạn).


1

Đây là một câu hỏi cũ nhưng không có câu trả lời được chấp nhận, vì vậy tôi sẽ đề xuất điều này: thay đổi câu lệnh nhập trong hai.py để đọc:

from .. import one

Trong môi trường hiện tại của tôi (Python 3.6, VSCode sử dụng pylint 2.3.1), điều này sẽ xóa câu lệnh được gắn cờ.


1

Tôi tìm thấy một câu trả lời tốt đẹp . Chỉnh sửa pylintrc của bạn và thêm phần sau vào tổng thể

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

Khi bạn cài đặt Python, bạn có thể thiết lập đường dẫn. Nếu đường dẫn đã được xác định thì những gì bạn có thể làm là trong Mã VS, nhấn Ctrl + Shift + P và nhập Python: Chọn Phiên dịch và chọn phiên bản cập nhật của Python. Theo liên kết này để biết thêm thông tin, https://code.visualstudio.com/docs/python/envirments



0

Nếu bạn đang sử dụng Cython trong Linux, tôi đã giải quyết xóa module.cpython-XXm-X-linux-gnu.socác tệp trong thư mục đích dự án của tôi.


0

chỉ cần thêm mã này vào tệp .vscode / settings.json

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

Điều này sẽ thông báo vị trí của pylint (là công cụ kiểm tra lỗi cho python)


-1

Xin chào tôi đã có thể nhập các gói từ thư mục khác nhau. Tôi vừa làm như sau: Lưu ý: Tôi đang sử dụng VScode

Các bước để tạo gói Python Làm việc với các gói Python thực sự đơn giản. Tất cả bạn cần làm là:

Tạo một thư mục và đặt tên cho gói của bạn. Đặt các lớp học của bạn trong đó. Tạo một tập tin init .py trong thư mục

Ví dụ: bạn có một thư mục có tên là Framework nơi bạn đang lưu giữ tất cả các lớp tùy chỉnh ở đó và công việc của bạn là chỉ tạo một tệp init .py bên trong thư mục có tên là Framework.

Và trong khi nhập, bạn cần nhập theo kiểu này --->

từ cơ sở nhập khẩu khung

Vì vậy, lỗi E0401 biến mất Khung là thư mục mà bạn vừa tạo init .py và cơ sở là mô-đun tùy chỉnh mà bạn bắt buộc phải nhập vào và làm việc khi Hy vọng nó giúp !!!!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.