python 从包中导入模块

python import module from a package

文件夹结构:

<current dir>
   main.py
   packages <dir>
      __init__.py
      mod.py

主程序:

import packages
print packages.mod.hello()

mod.py:

def hello():
    return 'hello'

__init__.py:

from packages import mod

如果我 运行 main.py,我不会出错。但是,如果我将 __init__.py 编辑为 'from packages import *' ,则会出现此错误: AttributeError: 'module' object has no attribute 'mod'

我不是在问如何使 'print' 命令起作用。我可以在 main.py 中使用其他 'import' 语法来使其工作。问题是:我很好奇 __init__.py 中的那个 'from packages import mod'。如果我可以做 import mod 那么当我替换为 import * 时,这意味着导入所有内容,为什么我会收到错误?

那么 from packages import *__init__.py 中的真正含义是什么?

有人可以帮忙吗?谢谢

您可以直接加载同一个包中的模块。以下代码有效,它加载了 mod.py.

中的所有模块

里面__init__.py

from mod import *
print hello()

高效导入 - 仅加载 hello 函数

from mod import hello
print hello()

在您的代码中,from packages import * 您告诉解释器在 packages 中查找模块(与 __init__.py 在同一目录中)。但它在那里不存在。它存在于 __init__.py 之上的一个目录中。 (我怀疑我的术语有误)

这里有一个 reference 解释了如何加载包含包本身。

找到了

阅读 python 导入机制非常有趣。 Ref1 Ref2 Ref3

显然先加载父模块。例如,Ref3 指出,__init__.py 中的代码 import mod 会自动解释为 packages.mod。现在我必须找出如果你写 import packages.mod 会发生什么。 Ref1 更符合 python3 约定。请参阅它以获取更多信息。希望对你有帮助。

简答

那么from packages import *里面的__init__.py到底是什么意思?

__init__.py 导入自身。

说明

您只能导入模块,不能导入包。包只是模块或子包的容器。当你 "import" 一个包时,你实际上导入了模块 __init__.py.

__init__.py内容为:

from packages import mod

将模块 mod 导入 __init__.py。因此,它将可用 通过 packages.mod 在您的 main.py 中(记住 packages__init__.py 表示)。

当您将 __init__.py 的内容更改为:

from packages import *

您正在导入模块 __init__.py,与您所在的文件完全相同。 这有效(第二次导入只会触发 sys.modules 中的查找) 但不会给你 mod.

的内容

这意味着,您可以使用:

from module import *

但是你不能合理地使用这个空 __init__.py:

from package import *

因为 package 实际上是由 __init__.py 表示的 里面什么都没有。您可以检查这个(交互式或在文件中):

>>> import packages
>>> print(packages)
<module 'packages' from '/.../packages/__init__.py'>

__init__.py中你可以这样写:

from packages.mod import *

然后在 main.py:

print packages.hello()

有效。因为函数 hello() 现在在全局名称 space 中 文件 __init__.py.

在mozman的回答中提到,可以在__init__.py中使用__all__来 如果使用 from packages import *,则列出 should be imported 的模块。这是为这种情况设计的。

__init__.py只有这个内容:

__all__ = ['mod']

现在您可以在 main.py 中执行此操作:

from packages import *

print mod.hello()

如果您扩展 __init__.py

__all__ = ['mod']

from packages import *

您可以在 main.py 中执行此操作:

import packages

print packages.mod.hello()

但是,如果您从 __init__.py 中删除 from packages import *

__all__ = ['mod'] 

你会得到一个错误:

AttributeError: 'module' object has no attribute 'mod'

因为 __all__ 仅用于 from packages import * 情况。 现在我们回到 __init__.py 导入本身。

另请参阅:In Python, what exactly does “import *” import?

将 __all__ 添加到 packages.__init__:

__all__ = ['mod']
from packages import *

和模块 'mod' 将被导入,否则 'mod' 不在 'packages' 的命名空间中,但我无法解释为什么 'import *' 没有 __all__ 不导入 'mod'.