python 中的__init__.py的用法与个人理解
使用Python模块常见的情况是,事先写好A.py文件,需要import B.py文件时,先拷贝到当前目录,然后再import
这样的做法在程序量较小的情况下是可行的,如果程序交互复杂程度稍高,就很费力了
有一种解决方法可以将多个.py文件组织起来,方便在外部统一调用,和在内部互相调用:python中的 __init__.py在包调用中起到了重要的作用
首先要明确的Python在执行import包的时候,执行的操作,按照python的文档描述,操作如下:
a) 创建一个新的,空的module对象(它可能包含多个module);
b) 把这个module对象插入sys.module中
c) 装载module的代码(如果需要,首先必须编译) (首先需要找到module程序所在的位置,其原理为:如果需要导入的module的名字是m1,则解释器必须找到m1.py,它首先在当前目录查找,然后是在环境变量PYTHONPATH中查找)
d) 执行新的module中对应的代码。
Python中的package定义很简单,其层次结构与.py所在目录的层次结构相同,比较关键的一点是package中必须包含一个__init__.py的文件
例如,我们可以这样组织一个package: init为顶层目录

运行结果如下

其中__init__.py可以为空,只要它存在,解释器对其视作一个package处理。
第一层:pack, pack2, main.py
第二层 pack: __init__.py,module_A.py
pack2:__init__.py,module_B.py
main.py 调用脚本:
from pack import func1
from pack import func2
from pack2 import print_lst
def main():
func1()
func2()
print_lst() if __name__ == "__main__":
main()
其中 module_A:
def func1():
print("MODULEAAAAA_func1111") def func2():
print("MODULEAAAAA_func2222")
同一层 __init__.py
from .module_A import func1
from .module_A import func2
.module_A 表示__init__.py同一层目录的module_A
个人理解是:当 main.py调用脚本from pack import func1
由于from操作 会默认目录下存在pack包,解释器会首先寻找__init__.py
而__init__.py内容不为空,对module_A引入了两个函数fun1,fun2,生成了函数引用域(太菜不知道专属名词)
所以在main.py 中可以不显式地指明module_A而直接用: from pack import fun1,fun2
如果把pack下的init.py 的第二行 import func2注释

也就是说,package内的module的import 是受__init__.py限制的
有时在import语句中会出现通配符*,导入某个module中的所有元素,这是怎么实现的呢?
答案就在__init__.py中。如果在__init__.py文件中写(指定)
__all__ = ['module_A']
如果改为
__all__ = []
Traceback (most recent call last):
File "<stdin>", line , in <module>
ImportError: No module named module_A
运行则会报错,如上
这也就是说,package内的module的导入是受__init__.py限制的
好了,最后来看看,如何在package内部互相调用。
如果希望调用同一个package中的module,则直接import即可。
也就是说,在module_A.py中,可以直接使用import module_others
如果不在同一个package中,例如我们希望在module_A.py中调用module_B.py中的FuncB,则应该这样:
from module_B的包名(目录).module_B import funcB
python 中的__init__.py的用法与个人理解的更多相关文章
- 【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)
python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...
- Python中的__init__.py的作用
当用 import 导入该目录时,会执行 __init__.py 里面的代码 因此在__init__.py文件中,把深层的包的路径缩短,别的地方就可以在引用到目录级别时引到深层的包.
- Python中【__all__】的用法
Python中[__all__]的用法 转:http://python-china.org/t/725 用 __all__ 暴露接口 Python 可以在模块级别暴露接口: __all__ = [&q ...
- python2中的__init__.py文件的作用
python2中的__init__.py文件的作用: 1.python的每个模块的包中,都必须有一个__init__.py文件,有了这个文件,我们才能导入这个目录下的module. 2.__init_ ...
- Python中logging模块的基本用法
在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 ...
- Python中zip()与zip(*)的用法
目录 Python中zip()与zip(*)的用法 zip() 知识点来自leetcode最长公共前缀 Python中zip()与zip(*)的用法 可以看成是zip()为压缩,zip(*)是解压 z ...
- python中的__init__ 、__new__、__call__小结
这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs) 创建对象时调用,返回 ...
- 简单说明Python中的装饰器的用法
简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下 装饰器对与 ...
- Python中的__init__()和__call__()函数
Python中的__init__()和__call__()函数 在Python的class中有一些函数往往具有特殊的意义.__init__()和__call__()就是class很有用的两类特殊的函数 ...
随机推荐
- nginx配置虚拟机
在/usr/local/nginx/conf目录下nginx.conf文件是nginx的配置文件. 一.通过端口号区分虚拟机 在nginx.conf文件中添加一个Service节点,修改端口号: se ...
- MyBatis学习笔记(二) Executor
一.概述 当我们打开一个SqlSession的时候,我们就完成了操作数据库的第一步,那MyBatis是如何执行Sql的呢?其实MyBatis的增删改查都是通过Executor执行的,Executor和 ...
- cron和crontab命令详解 crontab 每分钟、每小时、每天、每周、每月、每年定时执行 crontab每5分钟执行一次
cron机制 cron可以让系统在指定的时间,去执行某个指定的工作,我们可以使用crontab指令来管理cron机制 crontab参数 -u:这个参数可以让我们去编辑其他 ...
- CSS :root 测试
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- SpringBoot设置文件上传大小限制--默认为1M
SpringBoot默认上传文件大小不能超过1MB,超过之后会报以下异常:org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeL ...
- vue.js及项目实战[笔记]— 03 vue.js插件
一. vue补充 1. 获取DOM元素 救命稻草,document.querySelector 在template中标示元素`ref = "xxx" 在要获取的时候,this.$r ...
- SAP FI配置步骤
http://blog.sina.com.cn/s/blog_8eda1a620100uwzj.html No. 配置对象 事务代码 配置内容 路径 备注 1 定义公司 OX15 企业结构>定义 ...
- 学习用Node.js和Elasticsearch构建搜索引擎(7):零停机时间更新索引配置或迁移索引
上一篇说到如果一个索引的mapping设置过了,想要修改type或analyzer,通常的做法是新建一个索引,重新设置mapping,再把数据同步过来. 那么如何实现零停机时间更新索引配置或迁移索引? ...
- C++反射机制:可变参数模板实现C++反射
1. 概要 本文描述一个通过C++可变参数模板实现C++反射机制的方法.该方法非常实用,在Nebula高性能网络框架中大量应用,实现了非常强大的动态加载动态创建功能.Nebula框架在Github ...
- 手把手教你全家桶之React(三)--完结篇
前言 本篇主要是讲一些全家桶的优化与完善,基础功能上一篇已经讲得差不多了.直接开始: Source Maps 当javaScript抛出异常时,我们会很想知道它发生在哪个文件的哪一行.但是webpac ...