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. Walkthrough: Create and use your own Dynamic Link Library (C++)

    参考网站:https://docs.microsoft.com/en-us/cpp/build/walkthrough-creating-and-using-a-dynamic-link-librar ...

  2. 把 nodejs koa2 制作的后台接口 部署到 腾讯云服务器

    我 使用 nodejs koa2框架 制作后端接口, 现在将nodejs koa2 部署到服务器 koa2项目 实现 接口 可以看我的 这篇文章: 简单实现 nodejs koa2 mysql 增删改 ...

  3. 高德Web开发入门之一

    高德Web开发 一.地图开发阐述 1)不管是高德地图的Web开发使用,亦或是百度地图的应用开发,都可以直接百度"高德地图/百度地图",进入地图首页下边"开放平台" ...

  4. 编写你的第一个Django应用

    安装 Python 作为一个 Python Web 框架,Django 需要 Python.更多细节请参见 我应该使用哪个版本的 Python 来配合 Django?. Python 包含了一个名为  ...

  5. 面试官:Redis的事务满足原子性吗?

    原创:码农参上(微信公众号ID:CODER_SANJYOU),欢迎分享,转载请保留出处. 谈起数据库的事务来,估计很多同学的第一反应都是ACID,而排在ACID中首位的A原子性,要求一个事务中的所有操 ...

  6. throw关键字

    1.基础用法 2.方法中加合法校验,告知方法的调用者 数组越界判断 3.一切皆为对象,创建的是运行期对象,则可以不处理(throws/try catch),直接交给JVM处理(打印并终止程序) 4.O ...

  7. Vite详解

    vite 目录 一.推荐两个插件插件 Volar Vue 3 Snippets 二.vite简介 优势分析 浏览器支持 三.vite搭建vue3.x项目 1.创建项目 2.集成Vue-Router 3 ...

  8. 生成随机uuid

      /**  * 生成随机uuid  */ export function uuid() {   return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.repla ...

  9. oracle报错注入的一些函数

    oracle 报错注入 select dbms_xmltranslations.extractxliff((select banner from sys.v_$version where rownum ...

  10. vue父组件中调用子组件的方法

    Vue项目中如何在父组件中直接调用子组件的方法: 方案一:通过ref直接调用子组件的方法: //父组件中 <template> <div> <Button @click= ...