__init__.py在Python源目录中用于什么?
当前回答
__init__.py允许的一件事是将模块转换为包,而不破坏API或创建无关的嵌套命名空间或私有模块*。这有助于我扩展命名空间。
如果我有一个包含
def foo():
...
然后用户将使用
from util import foo
如果我想为数据库交互添加实用程序函数,并且希望它们在util下有自己的命名空间,那么我需要一个新目录**,并且为了保持API兼容性(这样从util import foo仍然可以工作),我将其称为util/。我可以像这样将util.py移动到util/中,
util/
__init__.py
util.py
db.py
在util/__init__.py中
from util import *
但这是多余的。我们可以将util.py内容放在__init__.py中,而不是使用util/util.py文件,用户现在可以
from util import foo
from util.db import check_schema
我认为这很好地突出了util包的__init__.py的作用方式与util模块类似
*这在其他答案中有所暗示,但我想在这里强调一下**没有采用进口体操。请注意,创建与文件同名的新包是行不通的,请参见
其他回答
__init__.py:它是一个在包目录中找到的Python文件,在导入包或包中的模块时调用。您可以使用它来执行包初始化代码,即每当导入包时,在执行此文件夹中的其他模块之前,首先执行python语句。它类似于c或Java程序的主函数,但它存在于Python包模块(文件夹)中,而不是核心Python文件中。它还可以访问__init__.py文件中定义的全局变量,就像将模块导入Python文件一样。
例如。我在一个名为pymodlib的文件夹中有一个__init__.py文件,该文件包含以下语句:
print(f'Invoking __init__.py for {__name__}')
pystructures = ['for_loop', 'while__loop', 'ifCondition']
当我在解决方案模块、笔记本或python控制台中导入此包pymodlib时:这两条语句在导入时执行。因此,在日志或控制台中,您将看到以下输出:
>>> import pymodlib
Invoking __init__.py for pymodlib
在python控制台的下一条语句中:我可以访问全局变量:
>> pymodlib.pystructures
它给出以下输出:
['for_loop', 'while__loop', 'ifCondition']
现在,从Python3.3开始,可以选择使用该文件来使文件夹成为Python模块。因此,您可以跳过将其包含在python模块文件夹中。
自Python 3.3以来,__init__.py不再需要将目录定义为可导入的Python包。
检查PEP 420:隐式命名空间包:
对不需要__init__.py标记文件并且可以自动跨越多个路径段的包目录的本地支持(受PEP 420中描述的各种第三方命名空间包方法的启发)
测试如下:
$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
参考文献:https://docs.python.org/3/whatsnew/3.3.html#pep-420个隐式命名空间包https://www.python.org/dev/peps/pep-0420/Python 3中的包是否不需要__init__.py?
__init__.py将其所在的目录视为可加载模块。
对于喜欢阅读代码的人,我将二位炼金术士的评论放在这里。
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
名为__init__.py的文件用于将磁盘上的目录标记为Python包目录。如果你有文件
mydir/spam/__init__.py
mydir/spam/module.py
mydir在您的路径上,您可以将module.py中的代码导入为
import spam.module
or
from spam import module
如果删除__init__.py文件,Python将不再在该目录中查找子模块,因此导入模块的尝试将失败。
__init__.py文件通常为空,但可用于以更方便的名称导出包的选定部分,保存方便函数等。给定上面的示例,init模块的内容可以访问为
import spam
基于此
__init__.py文件使Python将包含它的目录视为模块。
此外,这是模块中要加载的第一个文件,因此您可以使用它来执行每次加载模块时要运行的代码,或者指定要导出的子模块。
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 将旋转的xtick标签与各自的xtick对齐
- 为什么元组可以包含可变项?
- 如何合并字典的字典?
- 如何创建类属性?
- 不区分大小写的“in”
- 在Python中获取迭代器中的元素个数
- 解析日期字符串并更改格式
- 使用try和。Python中的if
- 如何在Python中获得所有直接子目录