我正在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'
我该如何解决?
我知道有两种选择。
一,更改PYTHONPATH环境变量以包含模块上方的目录。
或者,编辑~/.pylintrc以包含模块上方的目录,如下所示:
[MASTER]
init-hook='import sys; sys.path.append("/path/to/root")'
(或者在其他版本的pylint中,init-hook要求您将[General]更改为[MASTER])
这两种选择都应该有效。
希望有所帮助。
这个pylint钩子目前是VScode中最好的方法,因为它内置的linter使用还不支持PYTHONPATH。
我使用MacVim和syntastic有同样的问题。如何配置prosector来修复导入错误?
相关博客文章,其中包含更多详细信息。
~/.pylintrc在OSX上为我工作,另一个没用
不知道为什么这不是公认的答案 - 同样值得一提的是那些绊脚石,你需要export PYTHONPATH以便pylint能够看到它(至少在bash / zsh中)
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
我似乎通过根据这个建议将pylint安装到我的virtualenv中来解决这个问题:plaidzooks.tumblr.com/post/36813101879
这很好用,应该是最好的答案。如果您没有.pylintrc设置,那么只需确保在您的主文件夹中快速pylint --generate-rcfile > .pylintrc。
改变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()具有相同的值。
确认这确实为E0611和E0401 pylint错误提供了解决方案。对于VSCode用户:重要的是打开的文件夹是"python根文件夹",并且.pylintrc在该文件夹中。
另外,请确保您的模块目录名称都不以.(点)开头。
你在两个目录中都有一个空的__init__.py文件让python知道dirs是模块吗?
当你没有从文件夹中运行时的基本轮廓(即可能来自pylint的,虽然我没有使用它)是:
topdir\
__init__.py
functions_etc.py
subdir\
__init__.py
other_functions.py
这就是python解释器在不引用当前目录的情况下知道模块的方式,因此如果pylint从其自己的绝对路径运行,它将能够以topdir.functions_etc或topdir.subdir.other_functions的形式访问functions_etc.py,前提是topdir在PYTHONPATH上。
更新:如果问题不是__init__.py文件,可能只是尝试复制或移动模块到c:\Python26\Lib\site-packages - 这是放置其他软件包的常见位置,并且肯定会在您的python路径上。如果你知道如何做Windows符号链接或等效的(我没有!),你可以这样做。这里有更多选项:http://docs.python.org/install/index.html,包括将sys.path附加到开发代码的用户级目录的选项,但实际上我通常只是象征性地链接我的本地开发目录到站点包 - 复制它具有相同的效果。
是的,我在两个目录中都有__init__.py。我认为问题是当PyLint运行时,顶级目录不在PYTHONPATH中,我不知道如何解决这个问题。
符号链接是一个好主意,但它只支持从Windows Vista开始,我正在运行XP。我想我可以尝试用它来硬连接......
重新连接:不,你最好不要这样做。我玩过它,虽然它肯定有效(在某种程度上),它不会像你期望的那样工作。
为什么,会发生什么?
符号链接不是一个好主意。这只能解决您机器上的问题 - 当其他人签出项目时,它将被破坏。
通过在venv下配置pylint路径可以解决这个问题:
$ cat .vscode / settings.json
{
"python.pythonPath":"venv/bin/python",
"python.linting.pylintPath":"venv/bin/pylint"
}
对于Windows,{ "python.pythonPath":"${workspaceFolder}\\.venv\\Scripts\\python.exe" "python.linting.pylintPath":"${workspaceFolder}\\.venv\\Scripts\\pylint.exe" }只是为了完整性。
我不知道它如何与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,而不是单个文件。不知何故,它设法找到导入的模块然后。
听起来很棒;怎么样?
@CeesTimmerman从父文件夹运行pylint ... dir。这要求__init__.py与.py文件一起存在于每个子文件夹中。
尝试
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并计划将模块用作包模块和包内的独立脚本,那么保持最佳状态可能是个好主意。
就像是
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添加到他那里,这比我的解决方案稍微优雅一点。 。)
关键是将项目目录添加到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/")'
我必须确认这摆脱了E0611 pylint错误,但E0401错误仍然存??在。
我有同样的问题,因为我找不到答案,我希望这可以帮助任何有类似问题的人。
我使用带有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)
希望这可以帮助。
也许通过在PYTHONPATH中手动附加目录?
sys.path.append(dirname)
嗯,但你会把那些代码放在哪里?在每个文件的顶部?我想它会起作用,但让PyLint工作真的很糟糕。
@Evgeny:看看Brian M. Hunt最近发布的答案。
并且在每个文件的顶部添加它不会出于某种原因 - PyLint似乎非常满足于忽略对其扫描的模块内的sys.path所做的任何修改。我没有费心去研究为什么,不过......
如果有人正在寻找一种方法来运行pylint作为PyCharm中的外部工具并让它与他们的虚拟环境一起工作(为什么我来到这个问题),这就是我如何解决它:
在PyCharm>首选项>工具>外部工具中,添加或编辑pylint项。
在"编辑工具"对话框的"工具设置"中,将"程序"设置为使用python解释器目录中的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__目录中。
您好我能够从不同的目录导入包。我刚刚做了以下事情:
注意:我正在使用VScode
创建Python包的步骤
使用Python包非常简单。你需要做的就是:
创建一个目录并为其提供包名称。
把你的课程放进去。
在目录中创建init.py文件
例如:你有一个名为Framework的文件夹,你在那里保留所有的自定义类,你的工作就是在名为Framework的文件夹中创建一个init.py文件。
而在导入时你需要以这种方式导入--->
来自Framework导入库
所以E0401错误消失了
Framework是您刚创建init.py和的文件夹
base是您需要导入并处理的自定义模块
希望能帮助到你!!!!