在 Python 中导入深度嵌套的模块
Posted
技术标签:
【中文标题】在 Python 中导入深度嵌套的模块【英文标题】:Importing deeply nested modules in Python 【发布时间】:2020-01-06 10:06:48 【问题描述】:考虑 Python 3.6 中的以下情况:
basepackage
|---__init__.py
|---package
|---__init__.py
|---subpackage
|---__init__.py
|---module.py
重要细节:在basepackage.package.__init__.py
里面有:
from basepackage.package.subpackage.module import AClass as AliasedClass
现在,假设在 basepackage.package.subpackage.module.py
内部我们要使用:
import basepackage.package.subpackage.module as aliased_module
[1]
结果是:
AttributeError: module 'basepackage' has no attribute 'package'
在罪魁祸首语句之后列出堆栈跟踪(按以下顺序):
from basepackage.package.subpackage.module import AClass as AliasedClass
import basepackage.package.subpackage.module as aliased_module
但如果不是 [1]
想使用:
from basepackage.package.subpackage import module as aliased_module
[2]
然后一切正常。
[1]
与 [2]
有何不同,以至于前者会导致错误,而后者不会?
【问题讨论】:
【参考方案1】:要使第一个选项 (import basepackage.package.subpackage.module as aliased_module
) 起作用,必须满足以下条件:
basepackage/__init__.py
必须包含类似于from . import package
的行(名称package
必须在此basepackage/__init__.py
文件中定义)
basepackage/package/__init__.py
必须包含类似于 from . import subpackage
的行
basepackage/package/subpackage/__init__.py
必须包含类似于 from . import module
的行
注意:__init__.py
文件中的 import 语句也可以是绝对路径而不是相对路径。
对于第二个选项(from basepackage.package.subpackage import module as aliased_module
),如果每个级别有空的__init__.py
文件就足够了,只要这些__init__.py
文件存在。
【讨论】:
谢谢。除了this section in the official docs 之外,您是否知道其他一些(更易于理解的)资源来了解这种行为? @z33k 也许这可以帮助realpython.com/python-modules-packages 与标准库有什么不同吗?因为我使用import xml.etree.ElementTree as ET
没有问题(注意ElementTree
是一个模块)并且我检查了源代码并且etree
包有一个空的__init__.py
并且在xml
的包中没有导入,只有@987654342 @ 已定义。
@z33k 嗯...也许我错了?我不知道,我很困惑,我不确定这个案子。在this part of the already linked tutorial 中,它似乎给出了一个与我在答案中的解释相反的例子。以上是关于在 Python 中导入深度嵌套的模块的主要内容,如果未能解决你的问题,请参考以下文章