Python __init__.py文件的作用
我们经常在python的模块目录中会看到 "__init__.py" 这个文件,那么它到底有什么作用呢?
1. 模块包(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代码文件。
因此可以将初始化代码放入该文件中。
至此。转载请注明出处。
Python __init__.py文件的作用的更多相关文章
- python中__init__.py文件的作用
问题 在执行models.py时,报ImportError:No module named transwarp.db的错误,但明明transwarp下就有db.py文件,路径也没有错误.真是想不通.后 ...
- Python包中 __init__.py文件的作用
原创连接 https://www.cnblogs.com/AlwinXu/p/5598543.html Python包中 __init__.py文件的作用 在创建python包的过程中,IDE都会在包 ...
- Python中__init__.py文件的作用详解
转自http://www.jb51.net/article/92863.htm Python中__init__.py文件的作用详解 http://www.jb51.net/article/86580. ...
- Python学习笔记之__init__.py文件的作用
参考地址:http://www.cnblogs.com/Lands-ljk/p/5880483.html Python __init__.py 作用详解 __init__.py 文件的作用是将文件夹变 ...
- 转载:【学习之家】Python中__init__.py文件的作用
Python中__init__.py文件的作用详解 Python中__init__.py文件的作用详解 来源:学习之家 作者:xuexi110 人气:357 发布时间:2016-09-29 摘要:__ ...
- python包中__init__.py文件的作用
python包中__init__.py文件的作用 __init__.py文件最常用的作用是标识一个文件夹是一个 python包. __init__.py文件的另一个作用是定义模糊导入时要导入的内容. ...
- python2中的__init__.py文件的作用
python2中的__init__.py文件的作用: 1.python的每个模块的包中,都必须有一个__init__.py文件,有了这个文件,我们才能导入这个目录下的module. 2.__init_ ...
- Python __init__.py 文件使用
__init__.py的主要作用是: 1. Python中package的标识,不能删除 2. 定义__all__用来模糊导入 3. 编写Python代码(不建议在__init__中写python模块 ...
- 初学者:__init__.py文件的作用
__init__.py 文件的作用及意义 __init__.py文件是一个包必须的文件,即使它是空的,但也是必须的,如果没有这个文件,python将不会把该文件夹当做一个package,而仅仅是一个d ...
随机推荐
- HttpSessionListener的用法
Session创建事件发生在每次一个新的session创建的时候,类似地Session失效事件发生在每次一个Session失效的时候. 这个接口也只包含两个方法,分别对应于Session的创建和失效: ...
- 了解Java内存模型,看完这一篇就够了
前言(此文草稿是年前写的,但由于杂事甚多一直未完善好.清明假无事,便收收尾发布了) 年关将近,个人工作学习怠惰了不少.两年前刚做开发的时候,信心满满想看看一个人通过自己的努力,最终能达到一个什么样的高 ...
- 03 使用Tensorflow做计算题
我们使用Tensorflow,计算((a+b)*c)^2/a,然后求平方根.看代码: import tensorflow as tf # 输入储存容器 a = tf.placeholder(tf.fl ...
- leetcode — permutation-sequence
import java.util.ArrayList; import java.util.List; /** * Source : https://oj.leetcode.com/problems/p ...
- 比MySQL快6倍 深度解析国内首个云原生数据库POLARDB的“王者荣耀”
随着移动互联网.电子商务的高速发展,被使用最多的企业级开源数据系统MySQL面临着巨大挑战——为迎接“双11"的高并发要提前做好分库分表;用户不断激增要将读写分离才能应对每天上亿次的访问,但 ...
- OpenCV添加中文(五)
OpenCV添加文字的方法putText(...),添加英文是没有问题的,但如果你要添加中文就会出现"???"的乱码,需要特殊处理一下. 下文提供封装好的(代码)方法,供OpenC ...
- 又是一个Notepad++的问题
昨天刚刚解决了Style Configurator无法保存的问题,今天继续解决另一个. 装好Notepad++之后,可以在右键菜单里面看到 Edit With Notepad++,win7里面挺好用的 ...
- MySQL中间件之ProxySQL(13):ProxySQL集群
返回ProxySQL系列文章:http://www.cnblogs.com/f-ck-need-u/p/7586194.html ProxySQL有原生的集群功能,但是这个原生的集群功能还正在试验阶段 ...
- spark之scala程序开发(本地运行模式):单词出现次数统计
准备工作: 将运行Scala-Eclipse的机器节点(CloudDeskTop)内存调整至4G,因为需要在该节点上跑本地(local)Spark程序,本地Spark程序会启动Worker进程耗用大量 ...
- Javascript 定时器调用传递参数的方法
文章来源: https://m.jb51.net/article/20880.htm 备注:先记下,以后整理: Javascript 定时器调用传递参数的方法,需要的朋友可以参考下. 无论是wind ...