PyLint“无法导入”错误-如何设置PYTHONPATH?
- 2025-01-21 09:01:00
- admin 原创
- 116
问题描述:
我在 Windows 上的 Wing IDE 内部运行 PyLint。我的项目中有一个子目录(包),在包内部,我从顶层导入了一个模块,即。
__init__.py
myapp.py
one.py
subdir\n __init__.py
two.py
two.py
我已经在里面了import one
,这在运行时工作正常,因为顶级目录(从中myapp.py
运行)位于 Python 路径中。但是,当我在 two.py 上运行 PyLint 时,它给出了一个错误:
F0401: Unable to import 'one'
我该如何修复这个问题?
解决方案 1:
我知道有两个选择。
一、更改PYTHONPATH
环境变量以包含模块上方的目录。
或者,编辑~/.pylintrc
以包含模块上方的目录,如下所示:
[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'
(或者在其他版本的 pylint 中,init-hook 要求您将 [General] 更改为 [MASTER])
这两个选项都应该可行。
解决方案 2:
更改路径的解决方案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()
。
解决方案 3:
可以通过在 venv 下配置 pylint 路径来解决该问题:$ cat .vscode/settings.json
{
"python.pythonPath": "venv/bin/python",
"python.linting.pylintPath": "venv/bin/pylint"
}
解决方案 4:
我pylintrc
在项目的根目录中添加了一个新文件
[MASTER]
init-hook='import sys; sys.path.append(".")'
它在 PyCharm IDE 中对我有用
解决方案 5:
创建.pylintrc
并添加
[MASTER]
init-hook="from pylint.config import find_pylintrc;
import os, sys; sys.path.append(os.path.dirname(find_pylintrc()))"
解决方案 6:
两个目录中是否有一个空__init__.py
文件可以让 python 知道这些目录是模块?
当您不在文件夹内运行时(即可能从 pylint 运行,尽管我没有使用过)基本概要是:
topdir\n __init__.py
functions_etc.py
subdir\n __init__.py
other_functions.py
这就是 Python 解释器无需引用当前目录就能知道模块的方式,所以如果 pylint 从它自己的绝对路径运行,它将能够functions_etc.py
以topdir.functions_etc
或 的形式访问topdir.subdir.other_functions
,只要topdir
在 上PYTHONPATH
。
更新:如果问题不在于__init__.py
文件,也许只需尝试复制或移动模块即可c:Python26Libsite-packages
——这是放置附加软件包的常见位置,并且肯定会在您的 pythonpath 上。如果您知道如何执行 Windows 符号链接或等效操作(我不知道!),您可以这样做。这里还有更多选项:http://docs.python.org/install/index.html,包括将开发代码的用户级目录附加到 sys.path 的选项,但实际上我通常只是将本地开发目录符号链接到 site-packages——将其复制过来具有相同的效果。
解决方案 7:
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
解决方案 8:
我不知道它如何与 WingIDE 一起工作,但为了将 PyLint 与 Geany 一起使用,我将外部命令设置为:
PYTHONPATH=${PYTHONPATH}:$(dirname %d) pylint --output-format=parseable --reports=n "%f"
其中 %f 是文件名,%d 是路径。可能对某些人有用 :)
解决方案 9:
我必须更新系统PYTHONPATH
变量以添加我的 App Engine 路径。就我而言,我只需编辑~/.bashrc
文件并添加以下行:
export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder
事实上,我尝试设置init-hook
第一个,但这并没有在我的代码库中一致地解决问题(不确定为什么)。一旦我将其添加到系统路径(通常这可能是一个好主意),我的问题就消失了。
解决方案 10:
尝试
if __name__ == '__main__':
from [whatever the name of your package is] import one
else:
import one
else
请注意,在 Python 3 中,子句中该部分的语法为
from .. import one
再想想,这可能无法解决您的特定问题。我误解了这个问题,以为 two.py 是作为主模块运行的,但事实并非如此。考虑到 Python 2.6(不导入absolute_import
from __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
执行导入时包含的目录。
(看看Brian的回答,你可能可以将前面的代码分配给init_hook
,但如果你要这样做,那么你可以简单地执行sys.path
他所做的附加操作,这比我的解决方案稍微优雅一些。)
解决方案 11:
我找到了一个很好的答案。编辑 pylintrc 并在 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'))"
解决方案 12:
如果您想从当前模块/文件向上寻找pylint
模块的根,这样就可以了。
[MASTER]
init-hook=sys.path += [os.path.abspath(os.path.join(os.path.sep, *sys.argv[-1].split(os.sep)[:i])) for i, _ in enumerate(sys.argv[-1].split(os.sep)) if os.path.isdir(os.path.abspath(os.path.join(os.path.sep, *sys.argv[-1].split(os.sep)[:i], '.git')))][::-1]
如果你有一个 python 模块~/code/mymodule/
,其顶级目录布局如下
~/code/mymodule/
├── .pylintrc
├── mymodule/
│ └── src.py
└── tests/
└── test_src.py
然后这将添加~/code/mymodule/
到你的 python 路径并允许 pylint 在你的 IDE 中运行,即使你mymodule.src
在 中导入tests/test_src.py
。
您可以用 a 替换掉 a 检查.pylintrc
,但是当涉及到 python 模块的根目录时,您通常需要 git 目录。
在你询问之前
使用的答案import sys, os; sys.path.append(...)
缺少一些可以证明我的答案格式的东西。我通常不会这样写代码,但在这种情况下,你只能处理 pylintrc 配置解析器和求值器的限制。它实际上是在init_hook 回调的上下文exec
中运行的,因此任何导入、使用多行语句、将某些内容存储到变量等的尝试都将失败。pathlib
我的代码的一个不那么令人厌恶的形式可能看起来像这样:
import os
import sys
def look_for_git_dirs(filename):
has_git_dir = []
filename_parts = filename.split(os.sep)
for i, _ in enumerate(filename_parts):
filename_part = os.path.abspath(os.path.join(os.path.sep, *filename_parts[:i]))
if os.path.isdir(os.path.join(filename_part, '.git')):
has_git_dir.append(filename_part)
return has_git_dir[::-1]
# don't use .append() in case there's < 1 or > 1 matches found
sys.path += look_for_git_dirs(sys.argv[-1])
我希望我能用pathlib.Path(filename).parents
它,事情就会变得容易得多。
解决方案 13:
这对我很有帮助!
.pylintrc
[MASTER]
; init-hook='import sys; sys.path.append("./venv/lib/python3.8/site-packages")'
; or
init-hook='import sys; sys.path.append(f"./venv/lib/python{sys.version[:3]}/site-packages");'
; or
;init-hook='from distutils.sysconfig import get_python_lib; sys.path.append(get_python_lib())'
; or
; init-hook='import site; sys.path.append(site.getsitepackages()[0])'
解决方案 14:
我遇到了同样的问题,但找到了不同的解决方案。这里介绍的一些解决方案对我来说不起作用或不理想。
首先,我正在使用的
pylint
版本3.0.3
不再find_pylintrc
存在。我不想在中使用绝对路径
init-root
。我希望 IDE 独立,因此无法调整 PyCharm 配置。
我希望它被提交到存储库,因此它必须为其他人工作并且不能包含绝对路径。
就我而言,解决方案是将以下代码片段添加到文件MAIN
的部分。(如果您使用的是不同版本的,pylintrc
可能会有所不同)。MAIN
`pylint`
[MAIN]
source-roots=repository/apps,src/apps
源根列表是绝对的,或者相对于被调用的工作文件夹,或者从 IDE 内部调用pylint
的项目根文件夹。pylint
解决方案 15:
我遇到了同样的问题,因为我找不到答案,所以我希望这可以帮助任何有类似问题的人。
我使用 flymake 和 epylint。基本上,我所做的就是添加一个 dired-mode-hook,检查 dired 目录是否是 python 包目录。如果是,我会将其添加到 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)
希望这有帮助。
解决方案 16:
关键是添加您的项目目录,而sys.path
无需考虑环境变量。
对于使用 VSCode 的人来说,如果你的项目有一个基目录,这里有一个单行解决方案:
[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
解决方案 17:
我遇到了同样的问题,并通过在我的 virtualenv 中安装 pylint 并将 .pylintrc 文件添加到我的项目目录中来解决了这个问题,文件中的内容如下:
[Master]
init-hook='sys.path = list(); sys.path.append("./Lib/site-packages/")'
解决方案 18:
安装 Python 时,您可以设置路径。如果路径已定义,那么您可以在 VS Code 中执行的操作是,按 Ctrl+Shift+P 并输入 Python:选择解释器并选择更新的 Python 版本。有关更多信息,请访问此链接:https://code.visualstudio.com/docs/python/environments
解决方案 19:
首先,转到 VS Code,然后按“ctrl + shift + p”
然后搜索settings.json
然后将下面的代码粘贴到settings.jason中。希望问题能够得到解决。
{
"python.pythonPath": "venv/bin/python",
"python.linting.pylintPath": "venv/bin/pylint"
}
解决方案 20:
我在尝试提交 PR 时遇到此错误。我最终所做的只是在“import”发生的同一行上添加 #pylint: disable=E0401。
这帮助我通过自动测试。
解决方案 21:
我刚刚发现的一个解决方法是实际上只对整个包运行 PyLint,而不是单个文件。不知何故,它设法找到了导入的模块。
解决方案 22:
这是一个老问题,但没有可接受的答案,因此我建议这样做:将 two.py 中的 import 语句更改为:
from .. import one
在我当前的环境中(Python 3.6,VSCode 使用 pylint 2.3.1),这会清除标记的语句。
解决方案 23:
我发现这在我的本地.pylintrc
文件中使用 pipenv 虚拟环境运行良好:
[MASTER]
init-hook='import site; sys.path += site.getsitepackages()'
请参阅此帖子以了解有关站点包的信息。
解决方案 24:
我在测试中导入我的库时遇到了这个问题:
repository\n .git\n ... All other files
src\n my_lib\n __init__.py
...
tests\n ... My tests files importing my_lib
可以通过在文件中添加以下方法来解决此问题.pylintrc
:例如,查找库的方法:
[MAIN]
source-roots=src/
解决方案 25:
如果有人正在寻找一种方法来在 PyCharm 中将 pylint 作为外部工具运行并使其与他们的虚拟环境一起工作(为什么我会想到这个问题),下面是我解决问题的方法:
在 PyCharm > 首选项 > 工具 > 外部工具中,添加或编辑 pylint 的项目。
在编辑工具对话框的工具设置中,将程序设置为使用来自 python 解释器目录的 pylint:
$PyInterpreterDirectory$/pylint
在参数字段中设置其他参数,例如:
--rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
将您的工作目录设置为
$FileDir$
现在使用 pylint 作为外部工具将使用通用配置文件在您选择的任何目录上运行 pylint,并使用为您的项目配置的任何解释器(大概是您的虚拟环境解释器)。
解决方案 26:
settings.json
Mac 用户:如果您使用的是带有 vsCode 的 Anaconda 3 并且拥有多个环境,则通过vsCode指向以下路径也可以:
{
"python.pythonPath": "/Users/username/opt/anaconda3/bin/python",
"python.linting.pylintPath": "/Users/username/opt/anaconda3/bin/python"
}
解决方案 27:
如果您使用的是 Windows:
获取刚刚创建的虚拟环境中 python.exe 的路径
应该是这样的
Z:YourProjectFolderScriptspython.exe
然后进入 vscode 并编辑用户
settings.json
添加以下行:
"python.pythonPath": "Z:\YourProjectFolder\Scripts\python.exe"
保存它,这样就可以解决问题
注意:将其放入 json 文件时,请使用双反斜杠,而不是单反斜杠
{
"python.pythonPath": "Z:\\YourProjectFolder\\Scripts\\python.exe"
}
解决方案 28:
您好,我能够从不同的目录导入包。我刚刚做了以下操作:注意:我使用的是 VScode
创建 Python 包的步骤使用 Python 包非常简单。您需要做的就是:
创建一个目录并赋予其您的包的名称。
把你的课程放进去。
在目录中创建 __init__.py 文件
例如:您有一个名为 Framework 的文件夹,您将所有自定义类保存在那里,您的工作就是在名为 Framework 的文件夹中创建一个 __init__.py 文件。
导入时您需要按以下方式导入--->
from Framework import base
因此 E0401 错误消失了 Framework 是您刚刚创建 __init__.py 的文件夹,base 是您需要导入并处理的自定义模块希望它有帮助!!!
解决方案 29:
对于 pylint >=3.0find_pylintrc
已被删除,相反您需要执行以下操作:
[MASTER]
init-hook="from pylint.config import find_default_config_files; import sys; sys.path.append(next(find_default_config_files()).parent.as_posix())"
这使用了新find_default_config_files
功能。
解决方案 30:
也许可以通过手动将目录附加到 PYTHONPATH 中来实现?
sys.path.append(dirname)