从包中导入python

时间:2016-04-09 09:49:22

标签: python import packages

文件夹结构:

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

主要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 *',则会出现此错误:属性错误:&#39;模块&#39;对象没有属性&#39; mod&#39;

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

那么from packages import *__init__.py内真正意味着什么?

任何人都可以提供帮助?感谢

3 个答案:

答案 0 :(得分:9)

简短回答

那么from packages import *__init__.py内真正意味着什么?

__init__.py导入自己。

说明

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

包含此内容的__init__.py

from packages import mod

将模块mod导入__init__.py。因此,它将可用 在main.py通过packages.mod(请记住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()现在位于全局名称空间中 档案__init__.py

正如mozman在回答中提到的,您可以在__all__中使用__init__.py 列出should be imported如果使用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导入本身。

答案 1 :(得分:1)

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

将__all__添加到包.__ init __:

__all__ = ['mod']
from packages import *

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

答案 2 :(得分:0)

您可以直接在同一个包中加载模块。以下代码有效,它加载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,解释了如何加载包含本身。

找到IT

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

显然首先加载父模块。例如,Ref3声明import mod内的代码__init__.py会自动解释为packages.mod。现在我必须找出如果你写import packages.mod会发生什么。 Ref1是python3约定的最新版本。请参阅以获取更多信息。希望这会对你有所帮助。