Python无法找到我包中的模块

4
我在Python中构建包时,可能缺少一些非常基础的东西。当我按照https://docs.python.org/2/tutorial/modules.html#packages的指南创建一个包并导入它时,Python找不到任何模块。例如,假设我创建了以下结构的包holygrail:
  • holygrail/
    • __init__.py
    • knights.py

我将__init__.py保持为空,因为文档说可以这样做,而我只是想创建一个基本的包开始使用。在knights.py中,我有如下代码:

def say():
     print 'Ni!'

如果我尝试使用import holygrail,Python不会报错,但是holygrail.knights.say()会导致Python告诉我"'module' object [holygrail] has no attribute 'knights'." 但是,如果我通过from holygrail import knights特别导入骑士,那么knights.say()就可以使用了。此外,holygrail.knights.say()也可以正常工作。
我尝试添加以下行:
__all__  = ['knights']

在__init__.py文件中进行了更改,但这并没有改变行为。
如何构建一个包,使得import package可以加载所有模块,从而允许像package.module.function()这样的语句?

1
在你的 init.py 文件中加入 import knights - Padraic Cunningham
2个回答

3
Python不会隐式导入整个包层次结构。您需要在__init__.py文件中明确指定要导入哪个级别的包内容。
当您在__init__.py中设置__all__ = ['knights']时,它仅适用于该模块的全部导入语句,例如:
>>> import holygrail
>>> holygrail.knights.say()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'knights'

>>> from holygrail import *
>>> knights.say()
Ni!

它还可以作为“导入所有(import all)”的过滤器,仅根据指定内容从模块中导入。
要在“import holygrail”上自动导入“knights”,您必须将“import knights”或“from . import knights”(参见intra-package or relative import)放入“__init__.py”中。您必须为每个模块都执行相同的操作。

1
import knights 加入到 __init__.py 中。
你提供的链接中确实说明了“在最简单的情况下,__init__.py 可以只是一个空文件……”你的示例不是最简单的情况,仅此而已。

这是一个不好的想法,因为在Python Zen中明确优于隐式。上面显然是隐式的情况;软件包的用户可能不希望发生这种情况,在这种特定情况下只会“帮助”(以节省大约10个字符的代价来使代码更难读)。 - Jerfov2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接