8

所以我正在使用由同事设置的模板,作为 python 的新手,我可能会遗漏一些非常明显的东西。

主目录有 init 文件,其中包含生成错误的主要 python 文件所需的模块。

同事用过:

from . import X

其中 X 是模块,但是当将此(和填充的初始化文件)复制到我自己的目录时,它会生成此错误:

ValueError:尝试在非包中进行相对导入

从谷歌和 SO 我了解到这是非常好的和合乎逻辑的,所以我想知道,作为一个新手,我错过了什么。

4

1 回答 1

17

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

当您使用脚本启动解释器时,此脚本将成为主模块,并具有匹配的名称__main__

使用 时import,会在搜索路径中搜索其他模块,您也可以使用sys.path. 的第一个条目sys.path通常为空,代表当前目录。

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

现在,当您在包含__init__.py文件的目录中执行脚本时,该脚本将变为__main__并且该目录不被视为包,因为它不在sys.path

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

根/
    包/
        __init__.py
        b.py
        py
    一个.py

当您python a.pyroot/目录运行时,您可以pkg/在此包中导入和使用相对导入(例如,from . import cinb.py__init__.py)。

python b.py从目录运行时pkg,不能使用相对导入,因为 Python 无法识别pkg为包:它不在sys.path. 对于 Python,pkg是一个普通的目录,不管它是否包含__init__.py. 的完全限定名称c.py是 just c, not pkg.c,所以亲戚from . import c不起作用。

于 2014-04-08T21:49:12.740 回答