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'
どうすれば修正できますか?
私が知っている2つのオプションがあります。
1つは、PYTHONPATH
環境変数を変更して、モジュールの上のディレクトリを含めることです。
または、~/.pylintrc
を編集して、次のようにモジュールの上のディレクトリを含めます。
[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'
(または、pylintの他のバージョンでは、init-hookは[General]を[MASTER]に変更する必要があります)
これらのオプションは両方とも機能するはずです。
お役に立てば幸いです。
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)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
両方のディレクトリに空の__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 実際には、通常、ローカル開発ディレクトリをサイトパッケージにシンボリックにリンクするだけです。コピーすると同じ効果があります。
この問題は、venvでpylintパスを構成することで解決できます。$ cat .vscode/settings.json
{
"python.pythonPath": "venv/bin/python",
"python.linting.pylintPath": "venv/bin/pylint"
}
WingIDEでどのように機能するかわかりませんが、GeanyでPyLintを使用するために、外部コマンドを次のように設定します。
PYTHONPATH=${PYTHONPATH}:$(dirname %d) pylint --output-format=parseable --reports=n "%f"
ここで、%fはファイル名で、%dはパスです。誰かに役立つかもしれません:)
システムPYTHONPATH
変数を更新して、App Engineパスを追加する必要がありました。私の場合、~/.bashrc
ファイルを編集して、次の行を追加する必要がありました。
export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder
実際、最初にinit-hook
を設定しようとしましたが、コードベース全体で一貫して問題を解決できませんでした(理由はわかりません)。システムパスに追加すると(おそらく一般的には良い考えです)、私の問題はなくなりました。
この同じ問題が発生したため、pylintをvirtualenvにインストールしてから、プロジェクトディレクトリに.pylintrcファイルを追加し、ファイルに次を追加して修正しました。
[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
私が発見したばかりの1つの回避策は、単一のファイルではなく、パッケージ全体に対して実際にPyLintを実行することです。どういうわけか、それはインポートされたモジュールを見つけることに成功します。
試して
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
に追加するだけで済みます。私のソリューションよりもエレガントです。)
重要なのは、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)
:cwd
をsys.path
に追加して、コマンドライン環境に合わせます
参考までに、ここに私の.pylintrcがあります:
https://Gist.github.com/chuyik/f0ffc41a6948b6c87c7160151ffe8c2f
私は同じ問題を抱えていましたが、答えが見つからなかったので、これが同様の問題を抱えている人の助けになることを願っています。
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)
お役に立てれば。
たぶん、PYTHONPATH内にディレクトリを手動で追加することによって?
sys.path.append(dirname)
誰かがPyCharmの外部ツールとしてpylintを実行し、仮想環境で動作させる方法を探している場合(なぜこの質問に来たのですか)、ここでそれを解決しました:
$PyInterpreterDirectory$/pylint
--rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
などの他のパラメータを設定します$FileDir$
に設定しますこれで、外部ツールとしてpylintを使用すると、共通の設定ファイルを使用して選択したディレクトリでpylintが実行され、プロジェクト用に設定されたインタープリター(おそらく、virtualenvインタープリター)が使用されます。
これは古い質問ですが、受け入れられた答えはありませんので、これをお勧めします。two.pyのimportステートメントを次のように変更します。
from .. import one
私の現在の環境(Python 3.6、pylint 2.3.1を使用するVSCode)では、これによりフラグ付きステートメントがクリアされます。
vscodeを使用する場合は、パッケージディレクトリが_pychache__ディレクトリにないことを確認してください。