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'

我该如何解决?

Answers:


144

我知道有两个选择。

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

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

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

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

这两个选项都应该起作用。

希望有帮助。


8
目前,此pylint钩是VScode中最好的方法,因为Pythonpath是内置的linter用法,尚不支持。
丹尼·史泰普

2
使用MacVim与syntastic时,我遇到相同的问题。如何配置prosector修复导入错误?
洛朗

相关博客文章,还有更多详细信息。
克里斯蒂安·朗

~/.pylintrc在OSX上为我工作,而另一个则不起作用
Miquel

不知道为什么这是不接受的答案-还值得一提的那些磕磕绊绊这一点,你需要export PYTHONPATHpylint看到它(至少在bash / zsh中)
马可Massenzio

43

更改路径的解决方案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 pylint错误提供了解决方案。对于VSCode用户:重要的是,打开的文件夹是“ python根文件夹”,并且.pylintrc在该文件夹中。
np8

另外,请确保所有模块目录名称均不以.(点)开头。
和Natalie

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(注意'和'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
我似乎已经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 '19

问题不要求该编辑器。
Ivailo Bardarov

VSCode现在显示以下消息:The setting "python.pythonPath" defined in your settings.json is now deprecated. 如果删除该python.pythonPath行,它似乎仍然可以工作。
杰西·奥尔德里奇

23

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

当您不在文件夹中运行时(例如,虽然不是我使用过的pylint),其基本轮廓是:

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

这是怎样的Python解释器知道不参考当前目录中的模块,因此,如果pylint的是从自身的绝对路径运行它就能访问functions_etc.pytopdir.functions_etctopdir.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 2009年

符号链接是一个好主意,但仅Windows Vista以后才支持,并且我正在运行XP。我想我可以尝试对其进行硬链接...
EMP

重新硬链接:不,最好不要这样做。我已经玩过它了,尽管它确实可以工作(以某种方式),但是它不会像您期望的那样工作。
shylent

符号链接不是一个好主意。这只能解决您计算机上的问题-当其他人签出项目时,该项目将对他们不利。
乔纳森·哈特利

12

我在此页面上找到的关于此问题的一般答案请不要打开,网站显示错误

创建.pylintrc并添加

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

5

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

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

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


4

我必须更新系统PYTHONPATH变量以添加我的App Engine路径。就我而言,我只需要编辑~/.bashrc文件并添加以下行:

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

实际上,我尝试设置第init-hook一个,但这不能在我的代码库中始终解决此问题(不确定原因)。一旦将其添加到系统路径中(一般来说可能是一个好主意),我的问题就消失了。


3

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


听起来不错;怎么样?
Cees Timmerman

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执行导入时包含的目录。

(查看Brian的答案,您可能会将先前的代码分配给init_hook,但是如果您打算这样做,则可以简单地对其进行附加sys.path操作,这比我的解决方案要优雅得多。)


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):添加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

1

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

sys.path.append(dirname)

嗯,但是您将代码放在哪里?在每个文件的顶部?我想它可以工作,但只是为了使PyLint正常工作是一个很大的突破。
EMP

@Evgeny:请参阅Brian M. Hunt最近发布的答案。
JAB

而且由于某些原因,将其添加到每个文件的顶部是行不通的-PyLint似乎很满足于忽略对其正在扫描的模块中对sys.path所做的任何修改。我没有去研究为什么,但是……
javawizard

1

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

我用飞配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)

希望这可以帮助。


1

如果有人在寻找一种方法来将Pylint作为PyCharm中的外部工具运行并使其与他们的虚拟环境一起工作(为什么我要问这个问题),那么我将通过以下方式解决它:

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

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


1

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

from .. import one

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


1

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



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软件包确实非常简单。您需要做的只是:

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

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

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

从Framework导入库

因此E0401错误消失了,Framework是您刚在其中创建init .py 的文件夹,而base是您要自定义的模块,您需要将其导入并在该模块上工作,希望它能有所帮助!!!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.