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. springboot中@Mapper和@Repository的区别

    @Mapper和@Repository是常用的两个注解,两者都是用在dao上,两者功能差不多,容易混淆,有必要清楚其细微区别: 区别: @Repository需要在Spring中配置扫描地址,然后生成 ...

  2. POI实现excel的导入导出

    引入依赖 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</arti ...

  3. mzy git学习,分支以及分支合并(四)

    git 鼓励大量使用分支:最后进行master和分支之间的合并 git branch git branch 查看当前有多少分支,并且将当前在使用的分支用*标注出来. [一定要注意git的分支有从属概念 ...

  4. Java事件模型

    1 import javax.swing.*; 2 import java.awt.event.*; 3 public class TestSourceListener { 4 5 public st ...

  5. gimp 缩放图片 python script

    滤镜 -> Python Fu -> 控制台,复制粘贴下面代码. 然后 scale_image(800, 800) 图片自动缩放为 800*800 了 这个代码是傻傻的缩放,你可以把它改成 ...

  6. 简单三分钟,本地搭建 k8s

    使用 minikube 在本地搭建 k8s 已经比以前要简单很多了.本文,我们通过简短的三分钟来重现一下在本地搭建 k8s 实验环境的步骤. Newbe.Claptrap 是一个用于轻松应对并发问题的 ...

  7. Spring系列之不同数据库异常如何抽象的?

    前言 使用Spring-Jdbc的情况下,在有些场景中,我们需要根据数据库报的异常类型的不同,来编写我们的业务代码.比如说,我们有这样一段逻辑,如果我们新插入的记录,存在唯一约束冲突,就会返回给客户端 ...

  8. ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!

    前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...

  9. NOIP模拟38:b

      这是T2.   一个容斥(其实也可以欧拉反演做,但是我不会).   首先开一个桶,记录第i行的j有多少个.   然后枚举1-\(maxn\),枚举他的值域内的倍数,记录倍数在第i行有多少个,将个数 ...

  10. 2021 年 9 月 TIOBE 指数 C# 增长突破 1.2%

    TIOBE 编程社区指数是编程语言流行程度的指标.该指数每月更新一次.评级基于全球熟练工程师.课程和第三方供应商的数量.谷歌.必应.雅虎.维基百科.亚马逊.YouTube 和百度等流行搜索引擎用于计算 ...