如何在包内导入模块

时间:2019-12-16 16:23:29

标签: python python-3.x python-import relative-import pep328

文件夹结构:

foo/
  bar.py
  __init__.py
test.py

foo/__init__.py具有import bar

我正在运行test.py的{​​{1}}


如何让import foo导入__init__.py

bar.py

Python为什么不为我的程序包创建新作用域,而将导入的根目录设为ModuleNotFoundError: No module named 'foo' 目录?

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

SyntaxError

两个不可接受的答案:

  • 我不能使用import .bar 。我需要import foo.bar程序包具有自己的独立层/范围,以便可以在计算机中的任何位置移动它并从任何位置导入它。这意味着根目录可能会更改,并且foo不会总是起作用。

  • 我无法将import foo.bar文件夹添加到我的路径。显然,这将使路径混乱,并且很容易发生名称冲突。从某种意义上说,应该将此软件包的文件与使用它的路径分开。


也许有一种解决方案可以将此软件包的目录仅添加到该软件包范围的路径中,位于foo中?

2 个答案:

答案 0 :(得分:3)

对于每个PEP 328'edition'语法纯粹用于绝对导入。由于df[df.Medals == 'silver'].groupby('edition').count()['Medals'].idxmax() >>> 1990 不是此处的顶级模块,因此唯一有效的import X语法是bar

import X的{​​{1}}导入import foo.bar的正确方法是:

bar

关于想要“绝对路径”,但也想要foo之类的观点是不可能的;即使__init__.py有效,也显然是相对路径(因为它仅相对于执行它的模块有意义; from . import bar 如果导入到import .bar包外部则没有意义)

至于“为什么Python不会为我的包创建新作用域,而将导入的根目录设为foo目录?”一个简单的例子就是假设您的子模块名为import .bar,而不是.bar。什么:

foo

在这种情况下意味着什么?如果这意味着您的子模块,那么如何获得内置的顶级math模块?这些问题(当我未能包含bar时在Python 2代码中遇到)是为什么 PEP 328,并且存在默认的绝对导入。一种语法始终是绝对语法(消除歧义),您可以在需要时使用相对导入语法执行相对导入(也无需歧义)。

答案 1 :(得分:-1)

好吧,您在__init__.py的{​​{1}}文件中遇到错误了吗?

好吧,这不应该让人大惊小怪,但是一个简单的替代方法是import bar

编辑
我知道该错误是由于层次结构而发生的,并且from . import bar具有顶级层次结构。
我发现以下article很有帮助。另请参见ShadowRanger's对这个问题的回答。

相关问题