我们经常在python的模块目录中会看到 "__init__.py" 这个文件,那么它到底有什么作用呢?
1. 标识该目录是一个python的模块包(module package)
如果你是使用python的相关IDE来进行开发,那么如果目录中存在该文件,该目录就会被识别为 module package 。
2. 简化模块导入操作
假设我们的模块包的目录结构如下:
. └── mypackage ├── subpackage_1 │ ├── test11.py │ └── test12.py ├── subpackage_2 │ ├── test21.py │ └── test22.py └── subpackage_3 ├── test31.py └── test32.py
如果我们使用最直接的导入方式,将整个文件拷贝到工程目录下,然后直接导入:
from mypackage.subpackage_1 import test11 from mypackage.subpackage_1 import test12 from mypackage.subpackage_2 import test21 from mypackage.subpackage_2 import test22 from mypackage.subpackage_3 import test31 from mypackage.subpackage_3 import test32
当然这个例子里面文件比较少,如果模块比较大,目录比较深的话,可能自己都记不清该如何导入。(很有可能,哪怕只想导入一个模块都要在目录中找很久)
这种情况下,__init__.py 就很有作用了。我们先来看看该文件是如何工作的。
2.1 __init__.py 是怎么工作的?
实际上,如果目录中包含了 __init__.py 时,当用 import 导入该目录时,会执行 __init__.py 里面的代码。
我们在mypackage目录下增加一个 __init__.py 文件来做一个实验:
. └── mypackage ├── __init__.py ├── subpackage_1 │ ├── test11.py │ └── test12.py ├── subpackage_2 │ ├── test21.py │ └── test22.py └── subpackage_3 ├── test31.py └── test32.py
mypackage/__init__.py 里面加一个print,如果执行了该文件就会输出:
print("You have imported mypackage")
下面直接用交互模式进行 import
> import mypackage You have imported mypackage
很显然,__init__.py 在包被导入时会被执行。
2.2 控制模块导入
我们再做一个实验,在 mypackage/__init__.py 添加以下语句:
from subpackage_1 import test11
我们导入 mypackage 试试:
> import mypackage Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/taopeng/Workspace/Test/mypackage/__init__.py", line 2, in <module> from subpackage_1 import test11 ImportError: No module named 'subpackage_1'
报错了。。。怎么回事?
原来,在我们执行import时,当前目录是不会变的(就算是执行子目录的文件),还是需要完整的包名。
from mypackage.subpackage_1 import test11
综上,我们可以在__init__.py 指定默认需要导入的模块
2.3 偷懒的导入方法
有时候我们在做导入时会偷懒,将包中的所有内容导入
from mypackage import *
这是怎么实现的呢? __all__ 变量就是干这个工作的。
__all__ 关联了一个模块列表,当执行 from xx import * 时,就会导入列表中的模块。我们将 __init__.py 修改为 。
__all__ = ['subpackage_1', 'subpackage_2']
这里没有包含 subpackage_3,是为了证明 __all__ 起作用了,而不是导入了所有子目录。
> from mypackage import * > dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'subpackage_1', 'subpackage_2'] > > dir(subpackage_1) ['__doc__', '__loader__', '__name__', '__package__', '__path__', '__spec__']
子目录的中的模块没有导入!!!
该例子中的导入等价于
from mypackage import subpackage_1, subpackage_2
因此,导入操作会继续查找 subpackage_1 和 subpackage_2 中的 __init__.py 并执行。(但是此时不会执行 import *)
我们在 subpackage_1 下添加 __init__.py 文件:
__all__ = ['test11', 'test12'] # 默认只导入test11 from mypackage.subpackage_1 import test11
再来导入试试
> from mypackage import * > dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'subpackage_1', 'subpackage_2'] > > dir(subpackage_1) ['__all__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__path__', '__spec__', 'test11']
如果想要导入子包的所有模块,则需要更精确指定。
> from mypackage.subpackage_1 import * > dir() ['__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'test11', 'test12']
3. 配置模块的初始化操作
在了解了 __init__.py 的工作原理后,应该能理解该文件就是一个正常的python代码文件。
因此可以将初始化代码放入该文件中。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]