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


165

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'

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

回答:


144

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

1つは、PYTHONPATHモジュールの上のディレクトリを含めるように環境変数を変更します。

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

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

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

これらのオプションはどちらも機能するはずです。

お役に立てば幸いです。


8
このpylintフックは、組み込みのリンター使用のためにPYTHONPATHがまだサポートされていないため、現在VScodeで最良の方法です。
ダニーステープル2017年

2
SyntasticでMacVimを使用しても同じ問題があります。インポートエラーを修正するようにプロセクタを設定するにはどうすればよいですか?
Laurent

いくつかの詳細を含む関連ブログの投稿
クリスチャンロング

~/.pylintrcOSXで私のために働いたが、他はうまくいかなかった
Miquel

なぜこれが受け入れられない答えであるのかわからない-また、これにつまずいた人たちに言及する価値があるexport PYTHONPATHので、それpylintを見るには(少なくともbash / zshで)必要がある
Marco Massenzio

42

パスを変更するソリューション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 2018年

また、モジュールのディレクトリ名が.(ドット)で始まっていないことを確認してください。
ソーモンとナタリー

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ではなく、virtualenvでPylintを使用したい場合がある

3)上記のように、init-hookを使用します( 'で注意を払い、「パイリントの解析は厳密です)

[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
Matt

3
これは非常に効果的で、最高の答えになるはずです。.pylintrcが設定されていない場合pylint --generate-rcfile > .pylintrcは、ホームフォルダーで簡単に確認してください。
reka18

26

問題はvenvの下でpylintパスを設定することで解決できます:$ 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

質問はこのエディタを求めていません。
Ivailo Bardarov

VSCodeに次のメッセージが表示されます。行The setting "python.pythonPath" defined in your settings.json is now deprecated. を削除しpython.pythonPathても、動作するようです。
Jesse Aldridge

23

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

フォルダ内から実行していないときの基本的なアウトライン(つまり、私は使用していませんが、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

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


1
はい、__init__.py両方のディレクトリにあります。問題は、PyLintの実行時に最上位のディレクトリがPYTHONPATHにないことであり、その修正方法がわかりません。
EMP

シンボリックリンクは良い考えですが、Windows Vista以降でのみサポートされており、XPを実行しています。私はそれをハードリンクしてみることができると思います...
EMP

再ハードリンク:いいえ、あなたはそれをしない方がいいです。私はそれを試してみましたが、確かに(ある意味では)機能しますが、期待どおりには機能しません。
shylent 2009

シンボリックリンクは良い考えではありません。これはあなたのマシンの問題を修正するだけです-他の誰かがプロジェクトをチェックアウトすると、彼らのためにそれは壊れます。
ジョナサンハートレイ

12

このページで見つけたこの質問に対する一般的な回答開かないでください、サイトはバグです

作成.pylintrcして追加

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

5

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

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

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


4

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

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

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


3

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


いいね; どうやって?
Cees Timmerman、2017

1
@CeesTimmerman pylint ... dir親フォルダーから実行します。これには__init__.py.pyファイルを含む各サブフォルダーに存在する必要があります。
yugr

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

念頭に置いて。

編集:そして今、あなたの実際の問題の可能な解決策のために。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

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

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

私はこれと同じ問題を抱えており、virtualenvにpylintをインストールしてから、.pylintrcファイルをプロジェクトディレクトリに追加して、次のファイルを追加しました。

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

これでE0611 pylintエラーが解消されることを確認する必要がありますが、E0401エラーは残ります。
np8 2018年

1

多分手動でPYTHONPATH内にディレクトリを追加することによって?

sys.path.append(dirname)

うーん、でもどこにそのコードを入れますか?すべてのファイルの上部にありますか?うまくいくと思いますが、PyLintを機能させるためだけのハックです。
EMP

@Evgeny:Brian M. Huntが最近投稿した回答をご覧ください。
JAB

そして、これをすべてのファイルの先頭に追加することは、何らかの理由で機能しません-PyLintは、スキャンしているモジュール内から行われたsys.pathへの変更を無視するのに完全に満足しているようです。でも、なぜか調べ
たく

1

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

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

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

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

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


1

これは古い質問ですが、受け入れられた答えはないので、これをお勧めします:two.pyのインポートステートメントを変更して、

from .. import one

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


1

良い答えを見つけました。あなたのpylintrcを編集して、マスターに以下を追加してください

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コード内で実行できることは、Ctrl + Shift + Pを押して「Python:Type Interpreter」を選択し、更新されたバージョンのPythonを選択します。詳細については、このリンクに従ってください。https://code.visualstudio.com/docs/python/environments



0

LinuxでCythonを使用している場合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という名前のフォルダーがあり、そこにすべてのカスタムクラスを保持している場合、Frameworkという名前のフォルダー内にinit .pyファイルを作成するだけです。

そして、インポート中は、この方法でインポートする必要があります--->

フレームワークインポートベースから

E0401エラーが消えるフレームワークはinit .pyを作成したフォルダーであり、ベースはカスタムモジュールにインポートして作業する必要があるカスタムモジュールです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.