不带 from 子句的 Python import 语句导入类而不是模块

标签 python python-3.x python-import

如下面的简单测试用例所示,当在包的 __init__.py 中导入该类时,导入语句会导入一个类,而不是同名的模块。

这是预期的行为还是错误?无论哪种情况,如果任何人都可以引用任何相关文档或错误报告,那将会很有帮助。如果出现错误,那么了解预期的行为是什么会很有用:应该导入模块 pkg.a,还是应该引发错误?

包布局

C:\...\imp_test
|
\---pkg
        a.py
        __init__.py

文件

__init__.py

from .a import a

a.py

class a:
    pass

结果

C:\...\imp_test> python
Python 3.7.1 (default, Dec 10 2018, 22:54:23)
[MSC v.1915 64 bit (AMD64)] :: Anaconda custom (64-bit) on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pkg.a
>>> type(pkg.a)
<class 'type'>
>>> var = pkg.a()
>>>

最佳答案

更新:

这是 pkg 中绑定(bind) a 的模块与 pkg 中绑定(bind) a 的变量之间的命名空间冲突。 这是预期行为,如 here 中所述。

旧:

我相信这是因为 import 语句使用了 finder。 查找器会先搜索包,然后再搜索模块路径,因为它找到匹配的路径,所以立即返回。

我查看了 python 导入文档 here并发现了这个小片段

When the name variable is of the form package.module, normally, the top-level package (the name up till the first dot) is returned, not the module named by name. However, when a non-empty fromlist argument is given, the module named by name is returned.

如果你想强制导入模块,可以使用 import_module 函数

import importlib
a = importlib.import_module('pkg.a')

关于不带 from 子句的 Python import 语句导入类而不是模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57701931/

相关文章:

python - 无法通过 Python 中的扭曲将索引从列表“复制”到另一个索引

c# - Pythonnet如何正确停止脚本执行

python - 解析 <item> 标签的 XML RSS feed 字节流

python - 如何在 Arch Linux 中安装 Python 3.8 和 Python 3.9?

python - 按下按钮后多次更改 tkinter 输入小部件

Python:如何导入没有 python-filename 作为子模块的模块?

python-3.x - 通过 for 循环创建多个命名数据框

python - 神秘的 OpenCv 错误

python-3.x - 尝试在没有已知父包的情况下进行相对导入

Python 可以导入未安装的模块