PyLint“无法导入”错误 - 如何设置PYTHONPATH?

时间:2009-12-14 07:22:05

标签: python virtualenv 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'

我该如何解决这个问题?

29 个答案:

答案 0 :(得分:110)

我知道有两种选择。

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

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

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

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

这两个选项都应该有用。

希望有所帮助。

答案 1 :(得分:22)

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

答案 2 :(得分:21)

我在此页面PLEASE NOT OPEN, SITE IS BUGED上找到的

这个问题的一般答案

创建.pylintrc并添加

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

答案 3 :(得分:20)

改变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()具有相同的值。

答案 4 :(得分:16)

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

当你没有从文件夹中运行时的基本轮廓(即可能来自pylint的,虽然我还没有使用过):

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

这就是python解释器在不引用当前目录的情况下知道模块的方式,因此如果pylint从其自己的绝对路径运行,它将能够以functions_etc.pytopdir.functions_etc访问topdir.subdir.other_functions {1}},topdir上提供PYTHONPATH

更新:如果问题不是__init__.py文件,可能只是尝试将模块复制或移动到c:\Python26\Lib\site-packages - 这是放置其他软件包的常见位置,肯定会在您的PYTHONPATH。如果你知道如何做Windows符号链接或等效的(我没有!),你可以这样做。还有更多选项here: http://docs.python.org/install/index.html,包括将sys.path附加到开发代码的用户级目录的选项,但实际上我通常只是象征性地将我的本地开发目录链接到site-packages - 将其复制过来具有相同的效果。

答案 5 :(得分:9)

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

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

它在 PyCharm IDE 中对我有用

答案 6 :(得分:8)

可以通过在venv下配置pylint路径来解决该问题: $ cat .vscode / settings.json

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

答案 7 :(得分:5)

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

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

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

答案 8 :(得分:4)

我必须更新系统 using (XmlReader reader = XmlReader.Create(OriginalXml)) { XmlWriterSettings ws = new XmlWriterSettings(); ws.Indent = true; using (XmlWriter writer = XmlWriter.Create(FilteredXml, ws)) { int skip = 0; while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: skip += reader.Name.Equals(RemoveMe) ? 1 : 0; if (skip == 0) { writer.WriteStartElement(reader.Name); while (reader.MoveToNextAttribute()) writer.WriteAttributeString(reader.Name, reader.Value); } break; case XmlNodeType.Text: if (skip == 0) { writer.WriteString(reader.Value); } break; case XmlNodeType.XmlDeclaration: case XmlNodeType.ProcessingInstruction: if (skip == 0) { writer.WriteProcessingInstruction(reader.Name, reader.Value); } break; case XmlNodeType.Comment: if (skip == 0) { writer.WriteComment(reader.Value); } break; case XmlNodeType.EndElement: if (skip == 0) { writer.WriteFullEndElement(); } skip -= reader.Name.Equals(RemoveMe) ? 1 : 0; if (skip < 0) { throw new Exception("wrong sequence"); } break; } } } } 变量才能添加我的App Engine路径。在我的情况下,我只需编辑我的PYTHONPATH文件并添加以下行:

~/.bashrc

事实上,我首先尝试设置export PYTHONPATH=$PYTHONPATH:/path/to/google_appengine_folder,但这并没有在我的代码库中一致地解决问题(不确定原因)。一旦我将它添加到系统路径(一般来说可能是一个好主意),我的问题就消失了。

答案 9 :(得分:3)

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

答案 10 :(得分:2)

<击>尝试

<击>
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的目录。

(看看Brian的回答,您可以将之前的代码分配给init_hook,但是如果您要这样做,那么您可以简单地将sys.path附加到他所做的那个,比我的解决方案稍微优雅一点。)

答案 11 :(得分:2)

关键是将项目目录添加到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

答案 12 :(得分:2)

我有同样的问题并通过在我的virtualenv中安装pylint然后将.pylintrc文件添加到我的项目目录中来修复它,文件中包含以下内容:

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

答案 13 :(得分:2)

我刚刚发现的一个解决方法是实际上只为整个包运行PyLint,而不是单个文件。不知何故,它设法找到导入的模块。

答案 14 :(得分:1)

我在尝试提交 PR 时遇到此错误。我最终要做的只是在“导入”发生的同一行添加 #pylint: disable=E0401。

这有助于我通过自动测试。

答案 15 :(得分:1)

如果您使用的是 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"
}

答案 16 :(得分:1)

Mac 用户:如果您使用带有 vsCode 的 Anaconda 3 并且有多个环境,通过 settings.json 指向以下路径也适用于 vsCode:

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

答案 17 :(得分:1)

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

sys.path.append(dirname)

答案 18 :(得分:1)

我从https://sam.hooke.me/note/2019/01/call-python-script-from-pylint-init-hook/找到了一个不错的答案 编辑您的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'))"

答案 19 :(得分:1)

如果有人正在寻找一种方法在PyCharm中将pylint作为外部工具运行并让它与虚拟环境一起工作(为什么我会提到这个问题),这就是我解决它的方法:

  1. 在PyCharm中>偏好&gt;工具&gt;外部工具,添加或编辑pylint的项目。
  2. 在“编辑工具”对话框的“工具设置”中,将“程序”设置为使用python解释器目录中的pylint:$PyInterpreterDirectory$/pylint
  3. 在“参数”字段中设置其他参数,例如:--rcfile=$ProjectFileDir$/pylintrc -r n $FileDir$
  4. 将您的工作目录设置为$FileDir$
  5. 现在使用pylint作为外部工具将使用公共配置文件在您选择的任何目录上运行pylint,并使用为您的项目配置的任何解释器(可能是您的virtualenv解释器)。

答案 20 :(得分:1)

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

我使用带有epylint的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)

希望这有帮助。

答案 21 :(得分:0)

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

答案 22 :(得分:0)

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

,“ python.linting.pylintPath”:“ venv / bin / pylint”

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

答案 23 :(得分:0)

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

from .. import one

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

答案 24 :(得分:0)

如果您要从传递到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

您可以换成.pylintrc的支票,但是在python模块的根目录下,通常要使用git目录。

在你问之前

使用import sys, os; sys.path.append(...)的答案缺少可以证明我的答案格式合理的内容。我通常不会以这种方式编写代码,但是在这种情况下,您将不得不处理pylintrc配置解析器和评估程序的局限性。它实际上在the context of the init_hook callback中运行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来简化事情。

答案 25 :(得分:0)

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

答案 26 :(得分:0)

我发现这在带有 pipenv 虚拟环境的本地 .pylintrc 文件中运行良好:

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

有关网站软件包的信息,请参阅 this post

答案 27 :(得分:-1)

首先,进入您的VS代码,然后按“ ctrl + shift + p”

然后搜索settings.json

然后将下面的代码粘贴到settings.jason中。希望问题能够解决。

{

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

}

答案 28 :(得分:-1)

您好,我能够从其他目录导入软件包。我只是做了以下事情: 注意:我正在使用VScode

创建Python包的步骤 使用Python包真的很简单。您所需要做的就是:

创建一个目录,并为其指定软件包的名称。 将您的课程放进去。 在目录中创建一个 init .py文件

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

在导入时,您需要以这种方式导入--->

来自Framework导入库

因此E0401错误消失了 Framework是您刚创建的文件夹 init .py和 base是您要导入并在其中工作的自定义模块 希望能帮助到你!!!!