【发布时间】:2025-12-03 10:05:02
【问题描述】:
我刚刚在 python(2.7 和 3.x)中偶然发现了这种意外行为:
>>> import re as regexp
>>> regexp
<module 're' from '.../re.py'>
>>> from regexp import search
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'regexp'
from re import search 当然会成功,就像在我创建别名之前一样。但是为什么我不能使用别名regexp(现在是一个已知模块)作为导入名称的来源?
当一个模块有多个变体时,这会让您大吃一惊:假设我仍在使用 Python 2,并且我想使用 C 版本的 pickle、cPickle。如果我尝试从pickle 导入名称,它将从简单的pickle 模块中获取(我不会注意到,因为它不会引发错误!)
>>> import cPickle as pickle
>>> from pickle import dump
>>> import inspect
>>> inspect.getsourcefile(dump)
'.../python2.7/pickle.py' # Expected cPickle.dump
哎呀!
我发现sys.modules 包含真正的模块名称(re 或cPickle,但不包括别名regexp 或pickle。这就解释了第二次导入的如何失败,但不是为什么 python 模块名称解析以这种方式工作,即这样做的规则和基本原理是什么。
注意:这被标记为与模块别名无关的a question 的重复:问题中甚至没有提到别名(这是关于从包中导入子模块)或最佳答案。尽管该问题的答案提供了与该问题相关的信息,但问题本身甚至与恕我直言。
【问题讨论】:
-
因为导入机制
import X或from X import Y不检查变量 X 的值,它会搜索名为“X”的文件/文件夹 -
而不是
from regexp import search和from pickle import dump,为什么不只是search = regexp.search和dump = pickle.dump? -
因为在您的示例中,它没有按预期工作?您的“令人讨厌的惊喜”场景根本没有吸引力,因为有一个清晰而简单的解决方法。并且作为@jmd_dk pointed out,您不能使用相同的语法从静态模块名称和变量模块名称导入,因为它是模棱两可的:Python 什么时候应该逐字解释模块名称而不是动态解释模块名称? Python 的禅宗说:面对歧义,拒绝猜测的诱惑
-
语法是
import MODULE as NAME。答案是模块和名称不可互换。模块可以是文件名XXX.py,也可以是搜索路径中包含相应__init__.py的文件。 -
我理解该答案的相关性,但问题不应该与作为重复项关闭相关吗?
标签: python