1

文件夹结构:

foo/
  bar.py
  __init__.py
test.py

foo/__init__.pyimport bar

我正在test.py跑步import foo


我如何__init__.py导入bar.py

ModuleNotFoundError: No module named 'foo'

为什么 Python 不为我的包创建新范围并为导入目录创建根foo目录?

相对路径似乎也不起作用(我收到了SyntaxError),尽管我正在寻找一种允许绝对路径的解决方案。

import .bar

两个不可接受的答案:

  • 我不能用import foo.bar。我需要这个foo包有自己独立的层/范围,这样我就可以在我的计算机中的任何地方移动它并从任何地方导入它。这意味着根可能会改变并且import foo.bar不会总是有效。

  • 我无法将foo文件夹添加到我的路径中。显然,这会使路径变得混乱,并且很容易发生名称冲突。开始的感觉会说这个包的文件应该与使用它的路径分开。


也许有一个解决方案可以将此包的目录添加到仅针对该包范围的路径中,在__init__.py?

4

2 回答 2

4

根据PEP 328import X语法纯粹用于绝对导入;因为bar这里不是顶级模块,所以唯一有效的import X语法是import foo.bar.

barfoo's导入的正确方法__init__.py是:

from . import bar

您关于想要“绝对路径”的观点,但也想要类似的东西import .bar是不可能的;即使import .bar有效,这显然是一个相对路径(因为它仅相对于执行它的模块才有意义;.bar如果在foo包之外导入则没有意义)。

至于“为什么 Python 不为我的包创建一个新的范围并将导入的根目录设置为 foo 目录?” 一个简单的例子是想象你的子模块被命名math,而不是bar。有什么作用:

import math

在这种情况下是什么意思?如果这意味着您的子模块,您如何获得内置的顶级math模块?这些问题(我在 Python 2 代码中遇到的问题是我未能 include 时遇到的from __future__ import absolute_import)是存在 PEP 328 和默认绝对导入的原因;一种语法始终是绝对的(消除歧义),您可以在需要时使用相对导入语法来执行相对导入(也没有歧义)。

于 2019-12-16T16:42:41.750 回答
-1

__init__.py好的,所以您的文件中有错误import bar吗?

好吧,这不应该爆炸,但一个简单的替代方法是from . import bar

编辑
我理解错误是由于层次结构而发生的,并且__init__.py具有顶级层次结构。
我发现以下文章很有帮助。另请参阅ShadowRanger对此问题的回答。

于 2019-12-16T16:32:32.017 回答