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'

我怎么解决这个问题?

398251 次浏览

你是否在两个目录中都有一个空的__init__.py文件来让python知道dirs是模块?

当你不是从文件夹中运行时(比如可能从pylint的文件夹中运行,尽管我没有用过),基本的大纲是:

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

这就是python解释器如何在不引用当前目录的情况下识别模块,因此如果pylint从自己的绝对路径运行,它将能够以topdir.functions_etctopdir.subdir.other_functions的形式访问functions_etc.py,前提是topdir位于PYTHONPATH上。

更新:如果问题不在__init__.py文件,也许只是尝试复制或移动你的模块到c:\Python26\Lib\site-packages——这是一个放置额外包的常见位置,并且肯定会在你的pythonpath上。如果你知道如何使用Windows符号链接或类似的方法(我不会!),你可以这样做。还有更多选项在这里:http://docs.python.org/install/index.html,包括附加sys. js的选项。路径与你的开发代码的用户级目录,但在实践中,我通常只是象征性地将我的本地开发目录链接到站点包-复制它具有相同的效果。

也许通过手动在PYTHONPATH中追加目录?

sys.path.append(dirname)

我刚刚发现的一个解决办法是,实际上只对整个包运行PyLint,而不是对单个文件运行PyLint。以某种方式,它设法找到导入的模块。

我知道有两个选择。

第一,改变PYTHONPATH环境变量以包含模块上面的目录。

或者,编辑~/.pylintrc以包含模块上面的目录,如下所示:

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

(或者在其他版本的pylint中,init-hook要求你将[General]更改为[MASTER])

这两种选择都应该有效。

<罢工>试

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(没有从__future__导入absolute_import)和Python 3方式的差异。x句柄导入,你不需要在Python 2.6中这样做,我不认为。

不过,如果你最终切换到Python 3,并计划将一个模块既用作包模块,又用作包内的独立脚本,那么保留它可能是一个好主意 就像< / p >
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,这比我的解决方案稍微优雅一些。)

我不知道它是如何与WingIDE一起工作的,但是为了与Geany一起使用PyLint,我将我的外部命令设置为:

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

其中%f是文件名,%d是路径。可能对某些人有用:)

我也有同样的问题,因为我找不到答案,我希望这可以帮助任何有类似问题的人。

我使用flymake与附页。基本上,我所做的就是添加一个dired-mode-hook来检查dired目录是否是python包目录。如果是,我将它添加到PYTHONPATH。在我的例子中,我认为一个目录是一个python包,如果它包含一个名为“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)

希望这能有所帮助。

1)系统。Path是一个列表。

2) 有时问题出在系统。Path不是你的virtualenv.path并且你想在你的virtualenv中使用pylint

3)就像上面说的,使用init-hook(注意' and " 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

如果有人正在寻找一种在PyCharm中运行pylint作为外部工具的方法,并让它在他们的虚拟环境中工作(为什么我想到这个问题),下面是我如何解决它:

  1. 在PyCharm > Preferences > Tools > External Tools中,为pylint添加或编辑一个项目。
  2. 在“编辑工具”对话框的“工具设置”中,将“程序”设置为使用python解释器目录:$PyInterpreterDirectory$/pylint中的pylint
  3. 在parameters字段中设置其他参数,如:--rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. 将工作目录设置为$FileDir$

现在使用pylint作为外部工具将在您使用公共配置文件选择的任何目录上运行pylint,并使用为您的项目配置的任何解释器(假设是您的virtualenv解释器)。

关键是将项目目录添加到sys.path,而不考虑env变量。

对于使用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

我也有同样的问题,并通过在我的virtualenv中安装pylint来修复它,然后在文件中添加一个.pylintrc文件到我的项目目录:

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

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()值相同。

我必须更新系统PYTHONPATH变量来添加我的应用程序引擎路径。在我的例子中,我只需要编辑我的~/.bashrc文件并添加以下一行:

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

事实上,我尝试先设置init-hook,但这并没有在我的代码库中始终解决这个问题(不确定为什么)。一旦我将它添加到系统路径(一般来说可能是一个好主意),我的问题就消失了。

你好,我能够从不同的目录导入包。我只是做了以下事情: 注意:我使用VScode

创建Python包的步骤 使用Python包非常简单。你所需要做的就是:

  • 创建一个目录,并给它您的包的名称。
  • 把你的课程放在里面。
  • 在该目录中创建__init__.py文件

例如:你有一个名为Framework的文件夹,你在那里保存了所有的自定义类,你的工作就是在名为Framework的文件夹中创建一个__init__.py文件。

而在进口时,你需要以这种方式进口——>

from Framework import base

, E0401错误消失 Framework是你刚刚创建__init__.py和 Base是您需要导入并处理的自定义模块 希望能有所帮助!!!!< / p >

如果使用vscode,请确保包目录不在_pychache__目录中。

可以通过配置venv下的pylint path来解决: $ cat .vscode/settings。json < / p >
{
"python.pythonPath": "venv/bin/python",
"python.linting.pylintPath": "venv/bin/pylint"
}

这是一个老问题,但没有公认的答案,所以我建议这样做:将import语句更改为two.py:

from .. import one

在我当前的环境中(Python 3.6, VSCode使用pylint 2.3.1),这将清除标记语句。

如果你在Linux中使用Cython,我解决了在我的项目目标目录中删除module.cpython-XXm-X-linux-gnu.so文件。

我找到了一个不错的回答。编辑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'))"

我在本页上找到了这个问题的一般答案请不要打开,网站有窃听器

创建.pylintrc并添加

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

只需在.vscode/settings.json文件中添加此代码

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

这将通知pylint的位置(这是python的错误检查器)

安装Python时,可以设置路径。如果path已经定义了,那么你可以在VS Code中,按Ctrl+Shift+P,输入Python:选择解释器,然后选择Python的更新版本。点击此链接获取更多信息,https://code.visualstudio.com/docs/python/environments

首先,进入VS Code,然后按“ctrl + shift + p"

然后搜索settings.json

然后将下面的代码粘贴到设置中。我希望问题能够解决。

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

如果你想从传递给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中运行,即使你在tests/test_src.py中导入mymodule.src

你可以用.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,这将使事情变得更容易。

Mac用户:如果你正在使用Anaconda 3 w/ vsCode,并且有多个环境,通过settings.json指向以下路径for vsCode也可以:

{
"python.pythonPath": "/Users/username/opt/anaconda3/bin/python",
"python.linting.pylintPath": "/Users/username/opt/anaconda3/bin/python"
}

我在项目的根目录中添加了一个新文件pylintrc

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

它在PyCharm IDE中为我工作

如果你使用的是Windows:

  • 获取刚刚创建的虚拟环境中python.exe的路径
  • 它应该像这样Z:\YourProjectFolder\Scripts\python.exe
  • 然后转到vscode并编辑用户settings.json
  • 添加这一行:"python.pythonPath": "Z:\\YourProjectFolder\\Scripts\\python.exe"
  • 保存它,这应该可以解决问题
  • 注意:在json文件中使用双反斜杠而不是单反斜杠
{
"python.pythonPath": "Z:\\YourProjectFolder\\Scripts\\python.exe"
}

我发现这在我的本地.pylintrc文件与pipenv虚拟环境中工作得很好:

[MASTER]
init-hook='import site; sys.path += site.getsitepackages()'

有关站点包的信息,请参见这篇文章

当我试图提交一个PR时,我得到了这个错误。我最终所做的只是在同一行添加#pylint: disable=E0401,其中"import"发生了。

这有助于我通过汽车考试。

我一直在努力解决这个问题,最终发现了一些没有在这里描述的东西。以下是我对这个问题的看法: 我在Windows上使用VS Code,使用虚拟环境。由于某些原因,pylint可执行文件被称为epylint而不是pylint。在我的脚本或CLI提示中,我正在运行pylint ./xxx,系统正在启动一个它在其他地方找到的pylint,但不是合适的。我只是在我的shell脚本中添加了一个e,我的“无法导入”问题最终消失了

编辑~ /。Pylintrc来包含你的模块上面的目录,像这样:

[MASTER]
init-hook='import sys,os;[sys.path.append("your_workspace_path"+di) for di in os.listdir("your_workspace_path")]'

把另一个可能的答案扔到堆里。我尝试了这里提供的许多解决方案。要么是我做错了,要么是我的pylint导入错误是由其他原因引起的。不管怎样,我的解决方法非常简单。

解决方案:重新安装包含您无法导入的所有模块的包(PyPi包而不是pip包),然后重新安装pylint,以便pylint和这些模块由相同的pip安装。

对我来说,拥有正确的目录并不管用。我从另一个关于他的问题的帖子中得到了这个想法。

这些都对我有用!

.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])'