从__init__.py文件的相对导入引发错误

the*_*lis 6 python relative-import

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

主目录有init文件,它有一个生成错误的主python文件所需的模块.

同事使用:

from . import X
Run Code Online (Sandbox Code Playgroud)

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

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

从谷歌和SO我收集到这是完美的和合乎逻辑的所以我想知道,作为一个新手,我错过了什么.

Fer*_*yer 11

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

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

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

搜索路径中的目录是包含__init__.py文件的包.

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

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

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

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

当您python b.pypkg目录运行时,您不能使用相对导入,因为Python无法识别pkg为包:它不在sys.path.对于Python来说,它pkg是一个普通的目录,无论它是否包含一个__init__.py.完全限定名称c.py只是c,不是pkg.c,所以亲戚from . import c不会工作.