python从包中导入模块

新手上路,请多包涵

文件夹结构:

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

主要内容:

 import packages
print packages.mod.hello()

模组.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' 语法使其工作。问题是:我很好奇 'from packages import mod'__init__.py 中。如果我可以做 import mod 那么当我替换为 import * 时,这意味着导入所有内容,为什么我会收到错误消息?

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

任何人都可以帮忙吗?谢谢

原文由 andio 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 391
2 个回答

简答

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

__init__.py 自行导入。

解释

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

__init__.py 内容如下:

 from packages import mod

将模块 mod 导入 __init__.py 。 Therefore, it will be available in your main.py via packages.mod (remember packages is represented by __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() 现在在文件的全局命名空间中 __init__.py

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

__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()

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

 __all__ = ['mod']

你会得到一个错误:

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

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

原文由 Mike Müller 发布,翻译遵循 CC BY-SA 3.0 许可协议

另请参阅: 在 Python 中,“import *”究竟导入了什么?

添加 all 到 packages.init:

 __all__ = ['mod']
from packages import *

并且模块’mod’将被导入,否则’mod’不在’packages’的命名空间中,但我无法解释为什么没有all的’import *‘不导入’mod’。

原文由 mozman 发布,翻译遵循 CC BY-SA 3.0 许可协议

推荐问题