没有__init__.py,但仍被视为包裹?

Ren*_*der 5 packages python-import python-3.4

A foobar package

  • foob​​ar的

    • __init__.py
    • foo.py
    • 酒吧

      • bar.py

Inside the __init__.py

from . import foo
from . import bar
Run Code Online (Sandbox Code Playgroud)

即使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首先导入这个?

David Beazley在整个主题上有一个惊人的教程.我刚才看过整件事,但我想我应该再看一遍,重新回顾一切.

FBi*_*idu 0

来自文档

\n
\n

模块是包含 Python 定义和语句的文件。文件名是模块名加上后缀.py。在模块内, module\xe2\x80\x99s 名称(作为字符串)可用作全局变量 的值__name__

\n

...

\n

包是一种使用 \xe2\x80\x9c 点模块名称\xe2\x80\x9d 构建 Python\xe2\x80\x99s 模块命名空间的方法。例如,模块名称 AB 指定名为 A 的包中名为 B 的子模块。

\n

...

\n

包支持另一种特殊属性,__path__. __init__.py在执行该文件中的代码之前,它被初始化为一个列表,其中包含保存 package\xe2\x80\x99s 的目录名称。该变量可以修改;这样做会影响将来对该包中包含的模块和子包的搜索。

\n

虽然不经常需要此功能,但它可用于扩展包中的模块集

\n
\n

所以是的,该__path__变量也应用于包内的模块,并且这些模块被视为“包的子模块”

\n

编辑\n在 Python 2.x 中,带有 的包from . import bar将在该行返回 an ImportError。在 Python 3.x 上, 的modulefoobar.foo类型为<module \'foobar.foo\' from \'../py/foobar/foo.py\'>和。foobar.bar<module \'foobar.bar\' (namespace)>

\n

显然,它出现在这里

\n
\n

常规包将继续具有 init.py 并将驻留在单个目录中。命名空间包不能包含 init.py

\n
\n