zoukankan      html  css  js  c++  java
  • 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

    PS:遇到问题没人解答?需要Python学习资料?可以加点击下方链接自行获取
    note.youdao.com/noteshare?id=2dce86d0c2588ae7c0a88bee34324d76

    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 1, 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

  • 相关阅读:
    如何创建支持64位的安装程序
    SharePoint Server 2013开发之旅(四):配置工作流开发和测试环境
    SharePoint Server 2013开发之旅(三):为SharePoint Server配置App开发、部署、管理环境
    SharePoint Server 2013开发之旅(二):使用在线的开发人员网站进行SharePoint App开发
    SharePoint Server 2013开发之旅(一):新的开发平台和典型开发场景介绍
    在WPF应用程序中利用IEditableObject接口实现可撤销编辑的对象
    一个在ASP.NET中利用服务器控件GridView实现数据增删改查的例子
    关于未捕获异常的处理(WPF)
    牛刀小试:使用Reactive Extensions(Rx),对短时间内多次发生的事件限流
    如何对SharePoint网站进行预热(warmup)以提高响应速度
  • 原文地址:https://www.cnblogs.com/djdjdj123/p/12013549.html
Copyright © 2011-2022 走看看