A foobar package
foobar的
- __ init__.py
- foo.py
巴
- bar.py
Inside the __init__.py
from . import foo
from . import bar
即使bar
不是包或子包,它仍然作为模块(lolwut)导入。我在print(type(bar))
内执行__init__.py
检查了导入类型,并打印了<class 'module'>
......就是这样。这里发生了什么?它是一个模块对象,所以我做print(dir(bar))
,输出为['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
。现在,对我来说更令人困惑的是__path__
变量。这不是一个只包装的东西吗?
这就是所谓的命名空间包吗?我认为它不是,但我在__init__.py
文件中再试了一次 - 添加了一行import bar.bar
。它以ImportError
结尾。那么,总结一下我的问题,这个模块有用的是什么?为什么Python首先导入这个?
There's an amazing tutorial on this entire topic by David Beazley。我刚才看过整件事,但我想我应该再看一遍回忆一切。
答案 0 :(得分:0)
来自the docs
模块是包含Python定义和语句的文件。文件名是附加后缀.py的模块名称。在模块中,模块的名称(作为字符串)可用作全局变量
__name__
的值。...
包是一种使用“点模块名称”构建Python模块命名空间的方法。例如,模块名称A.B在名为A。
的包中指定名为B的子模块...
Packages支持另一个特殊属性
__path__
。这被初始化为一个列表,其中包含在执行该文件中的代码之前保存包__init__.py
的目录的名称。这个变量可以修改;这样做会影响将来对包中包含的模块和子包的搜索。虽然通常不需要此功能,但可用于扩展程序包中的模块集。
所以是的,__path__
变量也应用于包内的模块,这些模块被视为包的子模块&#39;
修改的
在Python 2.x中,包含from . import bar
的包将在该行返回ImportError
。在Python 3.x上,modulefoobar.foo
的{{1}}类型和<module 'foobar.foo' from '../py/foobar/foo.py'>
的{{1}}类型。
显然,它出现了here
常规包将继续具有init.py并将驻留在单个目录中。命名空间包不能包含init.py