2010-10-02 19 views
2

我正在尝试一个Python标准库模块,我们称之为foo.bar.baz当上级与当前目录中的模块匹配时,为什么导入虚线模块名称失败?

所以我写了开头

import foo.bar.baz 

一个小脚本并将其保存为foo.py

当我执行脚本时,我得到一个ImportError。我花了一段时间(我还在学习Python),但我终于意识到问题在于我如何命名脚本。一旦我将foo.py重命名为其他内容,问题就消失了。

所以我明白import foo声明将寻找脚本foo.py寻找标准库foo之前,但它不是我清楚,它正在寻找时,我说:import foo.bar.bazfoo.py是否有某种方式可以让该陈述的内容有意义?如果没有,为什么Python解释器没有继续寻找像foo/bar这样的目录层次结构和相应的__init__.py ?.

回答

6

import foo.bar.baz第一进口foo import语句,然后要求它bar,然后要求foo.barbaz。一旦进口,foo是否能够满足barbar.baz的要求对于foo的导入并不重要。这只是一个模块。只有一个foo模块。 import fooimport foo.bar.baz都会找到相同的模块 - 就像导入foo模块的其他方式一样。

实际上没有为foo是一个单独的模块,而不是一个包,仍然能够满足像import foo.bar.baz声明的方式:它可以增加"foo.bar""foo.bar.baz"sys.modules字典。这正是os模块为os.path所做的:它为平台导入正确的“路径”模块(posixpath,ntpath, os2path等),并将其分配给path属性。然后它确实sys.modules["os.path"] = path使该模块可导入为os.path,因此像import os.path这样的语句有效。没有理由这样做 - os.path可以不输入 - 但它是可能的。

+0

+1这是一个很好的答案,并且有很好的动机来了解整个进口流程。当你说导入语句[询问foo]导入栏时,你是否松散地使用'ask'这个词,或者是否有一些被调用的方法? – brainjam 2010-10-02 18:24:34

+0

我已经改变了措辞,因为我意识到这可能会被采取过于字面:)'__import__'函数会执行所有实际的导入操作,但它会先导入'foo',然后重新启动整个导入过程'foo.bar' - 这意味着(除其他外)它在'sys.modules ['foo.bar']'中查找并检查'sys.modules ['foo'] .__ path__'。 – 2010-10-02 18:47:12

+0

糟糕。现在是时候删除我的答案,因为我错了。 :-) – Omnifarious 2010-10-02 19:18:49