无法将模块导入同一目录和软件包

时间:2018-07-19 06:05:18

标签: python packages python-import

我正在使用from . import module语句来做到这一点:将本地模块导入脚本。脚本和模块位于同一文件夹中。

# module.py
def foo():
    print('Foo!')

# script.py
from . import module
module.foo()

> ImportError: cannot import name 'module'

这应该很容易,只需执行import module即可,但是正如this answer建议的那样,我将语句修改为前一种形式。

最终目标是要提供一个程序包,我可以从中使用东西,还需要在程序包中包含导入该程序包其他部分的可执行脚本。显然,经过几天的搜索和一些问题,我仍然不太了解进口和包装机械。

这些可能是原因:

  • 2.7和3.x中的导入语句不同,我使用的是3.6,问题在2.7上
  • 相对导入在包内部(带有__init__.py的文件夹)中是不同的
  • 工作目录不同或文件夹不在sys.path

至少在PyCharm中的新项目中,拥有__init__文件没有任何区别。另外,工作目录设置为源文件夹,位于path中。

我错过了什么吗?或更确切地说,实现最终目标中描述的功能的正确方法是什么?任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:1)

自从编写此答案以来,以我的拙见,我意识到用pip install -e .安装软件包并使用绝对导入是一种更方便,更好的样式。因此,即使在编写from package.sub.module import thing的程序包中也是如此。这使得重构变得容易得多,并且不需要操纵模块变量或sys.path


直接运行脚本时,Python将该脚本的名称(特殊变量__name__)视为"__main__"。如果是导入,则将名称设置为模块的名称。在后一种情况下,相对进口是可以的。但是import实际上是看__name__和另一个特殊变量__package__的组合,对于执行的脚本,它是None,但是对于导入的模块来说是模块的路径,例如parent.sub

搜索到的变量是... drumroll ...

__package__ + '.' + __name__

秘密成分正在操纵__package__

# script.py
__package__ = 'package_name'   # or parent.sub.package
from . import module

即使脚本直接执行,这也可以让Python知道您在包中的位置。但是,顶级文件夹必须位于sys.path中,并且程序包名称必须反映该目录结构。

有关相对进口的主题,请参见this very comprehensive answer

相关问题