使用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的用法与个人理解的更多相关文章

  1. 【转】【Python】Python中的__init__.py与模块导入(from import 找不到模块的问题)

    python中的Module是比较重要的概念.常见的情况是,事先写好一个.py文 件,在另一个文件中需要import时,将事先写好的.py文件拷贝 到当前目录,或者是在sys.path中增加事先写好的 ...

  2. Python中的__init__.py的作用

    当用 import 导入该目录时,会执行 __init__.py 里面的代码 因此在__init__.py文件中,把深层的包的路径缩短,别的地方就可以在引用到目录级别时引到深层的包.

  3. Python中【__all__】的用法

    Python中[__all__]的用法 转:http://python-china.org/t/725 用 __all__ 暴露接口 Python 可以在模块级别暴露接口: __all__ = [&q ...

  4. python2中的__init__.py文件的作用

    python2中的__init__.py文件的作用: 1.python的每个模块的包中,都必须有一个__init__.py文件,有了这个文件,我们才能导入这个目录下的module. 2.__init_ ...

  5. Python中logging模块的基本用法

    在 PyCon 2018 上,Mario Corchero 介绍了在开发过程中如何更方便轻松地记录日志的流程. 整个演讲的内容包括: 为什么日志记录非常重要 日志记录的流程是怎样的 怎样来进行日志记录 ...

  6. Python中zip()与zip(*)的用法

    目录 Python中zip()与zip(*)的用法 zip() 知识点来自leetcode最长公共前缀 Python中zip()与zip(*)的用法 可以看成是zip()为压缩,zip(*)是解压 z ...

  7. python中的__init__ 、__new__、__call__小结

    这篇文章主要介绍了python中的__init__ .__new__.__call__小结,需要的朋友可以参考下 1.__new__(cls, *args, **kwargs)  创建对象时调用,返回 ...

  8. 简单说明Python中的装饰器的用法

    简单说明Python中的装饰器的用法 这篇文章主要简单说明了Python中的装饰器的用法,装饰器在Python的进阶学习中非常重要,示例代码基于Python2.x,需要的朋友可以参考下   装饰器对与 ...

  9. Python中的__init__()和__call__()函数

    Python中的__init__()和__call__()函数 在Python的class中有一些函数往往具有特殊的意义.__init__()和__call__()就是class很有用的两类特殊的函数 ...

随机推荐

  1. Spring Security Oauth2 示例

    所有示例的依赖如下(均是SpringBoot项目) pom.xml <dependencies> <dependency> <groupId>org.springf ...

  2. Josephu(约瑟夫)问题解析

    Josephu问题为: 设置编号为1,2,3,......n的n个人围坐一圈,约定编号为k(1<=k<=n)的人从1看是报数,数到m的那个人出列,它的下一位又从1开始报数,数到m的那个人出 ...

  3. 【Spring】21、用spring目标对象处理Transaction rolled back because it has been marked as rollback-only

    在使用spring做事务管理时,很多人都会遇到这样一段异常: org.springframework.transaction.UnexpectedRollbackException: Transact ...

  4. MapperFacade自动导入失败

    MapperFacade自动导入失败 添加以下代码并且保证项目可以扫描到: @Configuration public class OrikaConfig { @Bean public MapperF ...

  5. java并发编程小结

    旭日Follow_24 的CSDN 博客 ,全文地址请点击: https://blog.csdn.net/xuri24/article/details/82078467 线程简介: 线程是操作系统调度 ...

  6. mysql日期时间函数

    日期时间函数1.取得当前日期时间SELECT NOW(), SYSDATE(),CURRENT_TIMESTAMP() FROM DUAL2.取得当前日期SELECT CURDATE(),CURREN ...

  7. HDU 1847 Good Luck in CET-4 Everybody!(找规律版巴什博奕)

    Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  8. Linux内核线程的思考与总结

    1.内核线程,只是一个称呼,实际上就是一个进程,有自己独立的TCB,参与内核调度,也参与内核抢占. 这个进程的特别之处有两点,第一.该进程没有前台.第二.永远在内核态中运行. 2.创建内核线程有两种方 ...

  9. XBanner的简单使用轮播

    导入依赖 implementation 'jp.wasabeef:glide-transformations:3.0.1' implementation 'com.xhb:xbanner:1.2.2' ...

  10. MyBatis笔记----@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class

    使用MyBatis 3.4.1或者其以上版本 @Intercepts({ @Signature(type = StatementHandler.class,  method = "prepa ...