文件夹结构:
<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
内真正意味着什么?
任何人都可以提供帮助?感谢
答案 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约定的最新版本。请参阅以获取更多信息。希望这会对你有所帮助。