web-dev-qa-db-ja.com

PyLint「インポートできません」エラー-PYTHONPATHの設定方法

WindowsのWing IDEの内部からPyLintを実行しています。プロジェクトにサブディレクトリ(パッケージ)があり、パッケージ内に最上位レベルからモジュールをインポートします。

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

two.pyの中にimport oneがあり、これは実行時に正常に機能します。トップレベルのディレクトリ(myapp.pyの実行元)はPythonパスにあるためです。ただし、two.pyでPyLintを実行すると、エラーが発生します。

F0401: Unable to import 'one'

どうすれば修正できますか?

123
EMP

私が知っている2つのオプションがあります。

1つは、PYTHONPATH環境変数を変更して、モジュールの上のディレクトリを含めることです。

または、~/.pylintrcを編集して、次のようにモジュールの上のディレクトリを含めます。

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

(または、pylintの他のバージョンでは、init-hookは[General]を[MASTER]に変更する必要があります)

これらのオプションは両方とも機能するはずです。

お役に立てば幸いです。

114
Brian M. Hunt

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()と同じ値を持つことに注意してください。

23
alex_koval

1)sys.pathはリストです。

2)問題はsys.pathがvirtualenv.pathではない場合があるであり、virtualenvでpylintを使用したい

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
23
macm

両方のディレクトリに空の__init__.pyファイルがあり、pythonにディレクトリがモジュールであることを知らせますか?

フォルダ内から実行していないときの基本的なアウトライン(つまり、おそらく私はそれを使用していませんが、pylintから)は次のとおりです。

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

これは、pythonインタープリターが現在のディレクトリを参照せずにモジュールを認識する方法です。したがって、pylintが独自の絶対パスから実行されている場合、topdirがオンであれば、functions_etc.pyまたはtopdir.functions_etcとしてtopdir.subdir.other_functionsにアクセスできますPYTHONPATH

更新:問題が__init__.pyファイルでない場合は、モジュールをc:\Python26\Lib\site-packagesにコピーまたは移動してみてください。これは、追加パッケージを置く一般的な場所であり、間違いなくpythonpathにあります。 Windowsシンボリックリンクまたは同等の方法(わからない!)を知っている場合は、代わりにそれを行うことができます。多くのオプションがあります ここ:http://docs.python.org/install/index.html 実際には、通常、ローカル開発ディレクトリをサイトパッケージにシンボリックにリンクするだけです。コピーすると同じ効果があります。

17
unmounted

この問題は、venvでpylintパスを構成することで解決できます。$ cat .vscode/settings.json

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

WingIDEでどのように機能するかわかりませんが、GeanyでPyLintを使用するために、外部コマンドを次のように設定します。

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

ここで、%fはファイル名で、%dはパスです。誰かに役立つかもしれません:)

5
simon

システムPYTHONPATH変数を更新して、App Engineパスを追加する必要がありました。私の場合、~/.bashrcファイルを編集して、次の行を追加する必要がありました。

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

実際、最初にinit-hookを設定しようとしましたが、コードベース全体で一貫して問題を解決できませんでした(理由はわかりません)。システムパスに追加すると(おそらく一般的には良い考えです)、私の問題はなくなりました。

4
Brian Moeskau

この同じ問題が発生したため、pylintをvirtualenvにインストールしてから、プロジェクトディレクトリに.pylintrcファイルを追加し、ファイルに次を追加して修正しました。

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

私が発見したばかりの1つの回避策は、単一のファイルではなく、パッケージ全体に対して実際にPyLintを実行することです。どういうわけか、それはインポートされたモジュールを見つけることに成功します。

2
EMP

試して

if __== '__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 __== '__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

念頭に置いて。

編集:そして今、あなたの実際の問題の可能な解決策について。 oneモジュールを含むディレクトリから(おそらくコマンドライン経由で)PyLintを実行するか、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
JAB

重要なのは、env変数を考慮せずにプロジェクトディレクトリをsys.pathに追加することです。

VSCodeを使用する人のために、プロジェクトのベースディレクトリがある場合の1行のソリューションを次に示します。

[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)cwdsys.pathに追加して、コマンドライン環境に合わせます


参考までに、ここに私の.pylintrcがあります:

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

2
chuyik

私は同じ問題を抱えていましたが、答えが見つからなかったので、これが同様の問題を抱えている人の助けになることを願っています。

Epylintでflymakeを使用します。基本的に私がやったことは、diredディレクトリがpythonパッケージディレクトリであるかどうかをチェックするdired-mode-hookを追加することでした。そうである場合、PYTHONPATHに追加します。私の場合、ディレクトリに「setup.py」という名前のファイルが含まれる場合、ディレクトリはpythonパッケージであると見なします。

;;;;;;;;;;;;;;;;;
;; 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
user2826500

たぶん、PYTHONPATH内にディレクトリを手動で追加することによって?

sys.path.append(dirname)
1
Mario Mikić

誰かがPyCharmの外部ツールとしてpylintを実行し、仮想環境で動作させる方法を探している場合(なぜこの質問に来たのですか)、ここでそれを解決しました:

  1. PyCharm>環境設定>ツール>外部ツールで、pylintのアイテムを追加または編集します。
  2. [ツールの編集]ダイアログの[ツール設定]で、pythonインタープリターディレクトリからpyintを使用するようにプログラムを設定します:$PyInterpreterDirectory$/pylint
  3. [パラメータ]フィールドで、--rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$などの他のパラメータを設定します
  4. 作業ディレクトリを$FileDir$に設定します

これで、外部ツールとしてpylintを使用すると、共通の設定ファイルを使用して選択したディレクトリでpylintが実行され、プロジェクト用に設定されたインタープリター(おそらく、virtualenvインタープリター)が使用されます。

1
tterry

これは古い質問ですが、受け入れられた答えはありませんので、これをお勧めします。two.pyのimportステートメントを次のように変更します。

from .. import one

私の現在の環境(Python 3.6、pylint 2.3.1を使用するVSCode)では、これによりフラグ付きステートメントがクリアされます。

0
Mike C

vscodeを使用する場合は、パッケージディレクトリが_pychache__ディレクトリにないことを確認してください。

0
Vikas Bhutani