2014-04-08 40 views
5

因此,我使用由同事设置的模板和作为python的新手我可能会丢失一些非常明显的东西。从__init__.py文件的相对导入抛出错误

主目录有init文件,其中有一个模块,我需要用于生成错误的主python文件。

使用同事:

from . import X 

其中X是模块,但复制这(和填充的init文件),以我自己的目录时,它会产生这个错误:

ValueError: Attempted relative import in non-package

从谷歌和所以我认为这是完美的和合乎逻辑的,所以我想知道,作为一个新手,我已经错过了。

+0

可能的重复[试图相对导入非包甚至\ _ \ _ init \ _ \ _。py](http://stackoverflow.com/questions/11536764/attempted-relative-import-in-non- package-even-with-init-py) –

+0

在这个建议中,他从标准的.py文件中提取。我的问题是关于从__init__.py文件拉。 – thewellis

+0

但你的问题有同样的原因。我希望我的回答能澄清你错误的原因。 –

回答

8

您必须了解Python如何处理模块。

当您使用脚本启动解释器时,此脚本将成为主模块,其名称为__main__

使用import时,在搜索路径中搜索其他模块,也可以使用sys.path访问(和更改)。 sys.path的第一项通常为空,代表当前目录。

如果搜索路径中包含__init__.py文件,则该搜索路径中的目录是一个包。

现在,当你包含一个__init__.py文件的目录中执行一个脚本,该脚本将成为__main__和目录不被视为一个包,因为它不是在sys.path

例如,请考虑以下的目录布局:

 
root/ 
    pkg/ 
     __init__.py 
     b.py 
     c.py 
    a.py 

当您从root/目录中运行python a.py,你可以导入pkg/,而该包中使用相对导入(例如,在b.py__init__.pyfrom . import c)。

当您从pkg目录中运行python b.py,则不能使用相对导入因为Python不承认pkg作为一个包:它不是在sys.path。对于Python,pkg是一个普通的目录,不管它是否包含__init__.pyc.py的完全限定名称仅为c,而不是pkg.c,因此相对的from . import c将不起作用。

+1

我想我明白了。由于相对导入的使用对于某个文件夹是本地的,因此它将生成错误,因为引用是循环的。我的同事在他的剧本中使用这种策略是很奇怪的。他所编码的大部分内容看起来都相当合乎逻辑和防水,也许他有一个Jenkins扩展或者解析它的东西。 – thewellis

相关问题