【问题标题】:Cannot import module in same directory and package无法在同一目录和包中导入模块
【发布时间】:2018-12-27 03:57:55
【问题描述】:

我正在使用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

拥有__init__ 文件至少在 PyCharm 中的新项目中并没有什么不同。此外,工作目录设置为源文件夹,位于path

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

【问题讨论】:

  • 我不认为你可以做相对导入,除非你在一个模块中。您的脚本不是模块。您也许可以将其称为模块python -m script,但是当您到达该阶段时,您可能没有正确地做事。

标签: python packages python-import


【解决方案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 关于相对导入的主题。

【讨论】:

    猜你喜欢
    • 2020-04-29
    • 2017-08-06
    • 2021-06-24
    • 1970-01-01
    • 2015-12-23
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多