Python错误 - ImportError:尝试相对导入,但没有已知的父包

21
所以,我的文件/文件夹结构如下:

So, my files/folders structure is the following:

--> 所以,我的文件/文件夹结构如下:

So, my files/folders structure is the following:

project/
├─ utils/
│  ├─ module.py
├─ server/
│  ├─ main.py

project/server/main.py文件中,我试图使用以下语法导入project/utils/module.py模块:from ..utils.module import my_function

我正在使用VSCode,它甚至在我键入模块路径时自动完成。但是当我运行project/server/main.py文件时,我会得到标题中的错误。

我已经阅读了stackoverflow上关于这个主题的几十个答案,但没有一个像这个例子一样。


1
如果你的项目不止一个文件,通常最好运行 python -m your.main.module 而不是 python your/main/module.py,这样 sys.path 将用于查找主模块,而不是根据主模块定义。 - o11c
在子目录中添加__init__.py文件,并设置PYTHONPATH=<projectdir>。 - drum
2个回答

38

这里有一个参考资料,很好地解释了这个问题。基本上,问题在于当运行独立脚本时,__package__ 没有被设置。

文件结构

.
└── project
    ├── server
    │   └── main.py
    └── utils
        └── module.py

项目/服务器/主要.py

if __name__ == '__main__':
    print(__package__)

输出

$ python3 project/server/main.py
None

我们可以看到,__package__ 的值为 None。这是一个问题,因为它是相对导入的基础,如此处所述:

__package__

……该属性用于计算主模块的显式相对导入,代替__name__,PEP 366中定义......

其中PEP 366进一步解释了这个问题:

主要提议的更改是引入一个新的模块级属性__package__。当它存在时,相对导入将基于这个属性而不是模块的__name__属性。

要解决这个问题,您可以通过-m标志将其作为模块运行,而不是作为独立脚本运行。

输出

$ python3 -m project.server.main  # This can be <python3 -m project.server> if the file was named project/server/__main__.py
project.server

项目/服务器/主要.py

from ..utils.module import my_function

if __name__ == '__main__':
    print(__package__)
    print("Main")
    my_function()

输出

$ python3 -m project.server.main
project.server
Main
My function

现在,__package__被设置了,这意味着它可以像上面文档中描述的那样解析显式相对导入。


0

您可以尝试直接使用import my_function而不是使用from ..util.module import my_function

如果不起作用,您需要在utils文件夹和server文件夹下创建一个名为__init__.py的空文件。 __init__.py将创建一个实际的模块,可供任何模块调用。


19
我确认在被调用模块和调用模块都创建 __init__.py 对我没有起作用。 - mercury

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接