1.  __init__.py

1.1  什么是__init__.py

  在Python3工程里,当python3检测到一个目录下存在__init__.py文件时,Python3就会把它当成一个模块(module)。__init__.py可以是一个空文件,也可以有内容。

1.2  为什么需要__init__.py

  使用Python3模块常见的情况是,在使用A.py时,需要import B.py,需要先拷贝到当前目录,然后再import,这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就会复杂费力。有一种解决方法可以将多个.py文件组织起来,方便在外部统一调用以及在内部互相调用。

Python3中的__init__.py在包调用中起到了重要的作用。首先要明确Python3在执行import包的时候,执行的操作,按照Python3的文档描述,操作如下:

  1. 创建一个新的module对象(它可能包含多个module);
  2. 把这个module对象插入sys.module中;
  3. 装载module的代码(首先需要找到module程序所在的位置,其原理为:如果需要导入的module的名字是m1,则解释器必须找到m1.py,它首先在当前目录查找,然后是在环境变量PYTHONPATH中查找)
  4. 执行新的module中对应的代码。

一个简单的package示例如图所示。

其中__init__.py为空,解释器对其视作一个package处理。

第一层:pack1, pack2, main.py

第二层:pack1: __init__.py,module_A.py

       pack2:__init__.py,module_B.py

  当main.py调用脚本from pack1 import Module_A,由于from操作,会默认目录下存在pack1包,解释器会首先寻找__init__.py。也就是说,package内module的import是受__init__.py限制的。

2.  Python3.3+的__init__.py

  Python 3.3+版本以后,Python3具有隐式命名空间包,允许它创建不带__init__.py文件的包,允许隐式名称空间包意味着可以完全放弃提供__init__.py文件的要求,并使其不受到影响。所以这就是在Python3.3以后的版本中,有时候工程中忘记加入了__init__.py文件而工程仍然能够正常运行的原因。

3. Python3中的PYTHONPATH

  PYTHONPATH是Python3中一个重要的环境变量,用于在导入模块的时候搜索路径。因为PYTHONPATH是Python3的搜索路径,所以默认我们import的模块都会从PYTHONPATH里面进行寻找。如果我们使用PYTHONPATH中的modules,那么在运行python3前,就要把path加到os.environ['PYTHONPATH'],如果在运行python3后再加,那些模块不能直接被导入。

  可以看到,路径列表的第一个元素为相对路径下的当前目录。由于在导入模块的时候,解释器会按照列表的顺序搜索,直到找到第一个模块,所以优先导入的模块为同一目录下的模块。导入模块时搜索路径的顺序也可以改变,分两种情况:

  1. 通过sys.path.append(),sys.path.insert()等方法来改变,这种方法当重新启动解释器的时候,原来的设置会失效。
  2. 改变PYTHONPATH,这种设置方法永久有效。在这种情况下,可以通过在sys.path列表显示的路径中添加.pth文件来实现。

4. 若要通过setup.py打包工程时,需要依赖__init__.py

  在Python3的PYTHONPATH中,包含Python3安装目录相关的一组路径(内置模块和标准库,以及其它第三方模块的共享路径),但是它不支持项目所在根目录这种形式,而是只支持文件所在目录的相对路径。以1.2小节中的示例,项目的根路径为D:\pytest_init,其中包含pack1(Module_A)和pack2(Module_B)包。项目根路径D:\pytest_init是需要放在PYTHONPATH中的,这样python解释器才可以通过包名互相访问。

  而setup.py所做的主要事情:将整个项目添加到PYTHONPATH中,setup.py中所记录的就是项目模块添加到PYTHONPATH的规则。setup.py中会定义此项目中有哪些模块需要被加入到PYTHONPATH,在这个过程中可以把测试项目过滤掉,而对项目中的模块进行打包时,setup.py会默认该模块包含并优先加载其中的__init__.py文件,因此在所要加入的每个模块中,都必须要有__init__.py文件的存在以保证所有需要导入的包都能够正确被找到并被导入。即,在使用setup.py打包的项目中,__init__.py必须包含在每个模块包的目录中,以便自动找到软件包,这样打包的软件包仅在包含__init__.py文件的情况下才能被识别。setup.py中还会定义需要的第三方依赖包,使用安装命令可以同时安装这些第三方依赖包等等。

python3之工程中必须依赖的__init__.py的更多相关文章

  1. 在Xcode5和Android Studio添加工程间的依赖

    正在编辑中,尚未完成 先看看ios的target是什么,请先参看http://www.cocoachina.com/bbs/read.php?tid-10884.html做个大概了解 这里有一篇文章, ...

  2. Python自定义Module中__init__.py文件介绍

    ./pyModuleTest/├── addutil│   ├── add.py│   ├── add.pyc│   ├── __init__.py│   ├── __init__.pyc│   └─ ...

  3. 转载:【学习之家】Python中__init__.py文件的作用

    Python中__init__.py文件的作用详解 Python中__init__.py文件的作用详解 来源:学习之家 作者:xuexi110 人气:357 发布时间:2016-09-29 摘要:__ ...

  4. python 中的__init__.py的用法与个人理解

    使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import 这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费 ...

  5. Python __init__.py 作用详解

    __init__.py 文件的作用是将文件夹变为一个Python模块,Python 中的每个模块的包中,都有__init__.py 文件. 通常__init__.py 文件为空,但是我们还可以为它增加 ...

  6. Python __init__.py 文件使用

    __init__.py的主要作用是: 1. Python中package的标识,不能删除 2. 定义__all__用来模糊导入 3. 编写Python代码(不建议在__init__中写python模块 ...

  7. Python学习笔记之__init__.py文件的作用

    参考地址:http://www.cnblogs.com/Lands-ljk/p/5880483.html Python __init__.py 作用详解 __init__.py 文件的作用是将文件夹变 ...

  8. 初学者:__init__.py文件的作用

    __init__.py 文件的作用及意义 __init__.py文件是一个包必须的文件,即使它是空的,但也是必须的,如果没有这个文件,python将不会把该文件夹当做一个package,而仅仅是一个d ...

  9. python3 module中__init__.py的需要注意的地方

    网上关于__init__.py的作用的资料到处都是,我在此就不再啰嗦哪些了. 若有需要.请各位看官去搜搜即可. 最近刚开始用Python3 就遇到了这个比较有意思的事情 闲言少叙,下面要介绍的是pyt ...

随机推荐

  1. mycat 分片的策略

    目的:有 user 和 t_order 两张数据表,表 user 的数据全部存放在 db1_zhang 中,表 t_order 的数据按 id 对 2 取模分别存放在 db1_zhang 和 db2_ ...

  2. 定时执行的任务Quartz.net

  3. WPF---数据绑定(一)

    一.何为数据绑定 场景:考虑一个Window上有一个TextBox和一个Slider两个元素,当我们拖动滑动条的时候,会在TextBox中显示当前滑动条的数值:当我们在TextBox中输入一个有效值, ...

  4. Mybatis一对一、一对多、多对多查询。+MYSQL

    场景:使用三张数据表:student学生表.teacher教师表.position职位表 一个学生可以有多为老师.一位老师可以有多个学生.但是一个老师只能有一个职位:教授.副教授.讲师:但是一个职位可 ...

  5. 关于Junit中Assert已经过时

    在junit4.12之后,Assert就过时了,提供了TestCase来取代: 同样在TestCase中原本比较常见的一些方法也已经取消了,例如:assertNotEquals.assertThat. ...

  6. Blazor+Dapr+K8s微服务之事件发布订阅

    我们要实现的是:在blazorweb服务中发布一个事件,并传递事件参数,然后在serviceapi1服务中订阅该事件,接收到blazorweb服务中发布的事件和参数. 1         在blazo ...

  7. 腾讯云 TKE Everywhere 特性发布,用户可在自有基础设施中托管 K8s 服务

    作者 孔令飞,腾讯云资深工程师,拥有大规模 Kubernetes 集群.微服务的研发和架构经验,目前专注于云原生混合云领域的基础架构开发. 朱翔,腾讯云容器服务高级产品经理,目前负责云原生混合云产品方 ...

  8. Python - 通过PyYaml库操作YAML文件

    PyYaml简单介绍 Python的PyYAML模块是Python的YAML解析器和生成器 它有个版本分水岭,就是5.1 读取YAML5.1之前的读取方法 def read_yaml(self, pa ...

  9. Qt 6.0精简WebEngine SerialPort Multimedia等成为半残GUI框架一览

    由于 Qt 集成了大量成熟模块,使之成为 C++ 领域中最好用的开源技术跨平台 GUI 开发框架.基于 Qt 能开发 Windows MacOS 传统桌面或无 GUI 应用程序.Unix/Linux ...

  10. C# Dapper基本三层架构使用 (一、架构关系)

    Dapper是一款轻量级ORM工具.如果你在小的项目中,使用Entity Framework.NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀.你又觉得ORM省时省力,这时Dapp ...