zoukankan      html  css  js  c++  java
  • 001---包和模块

    包和模块

    模块

    什么是模块?

    • 随着程序的功能越多,代码量越多。显然放一个文件不容易维护,为了编写可维护的代码。可以把函数分组,一个函数就是一个模块。
    • 在Python中,一个py文件就是一个模块(module)

    使用模块有什么好处

    • 大大提高了代码的可维护性
    • 可以避免函数名和变量名冲突,每个模块有自己独立的名称空间。

    分类

    • 内置模块:help(modules)可查看内置模块列表
    • 第三方模块:pip install module 联网安装
    • 自定义模块

    模块调用

    • 一旦调用模块,相当于执行了模块里的代码
    import os
    
    import time, json
    
    from decimal import Decimal
    
    from decimal import Decimal as d
    
    from django.views.decorators.csrf import csrf_exempt
    
    from django.shortcuts import *
    
    • 模块查找路径:python解释器会按照列表顺序依次每个目录去匹配你要导入的模块名,匹配到了就不会往后找。
    import sys
    print(sys.path)
    

    包是一种管理 Python 模块命名空间的形式,采用"点模块名称"。

    比如一个模块的名称是 A.B, 那么他表示一个包 A中的子模块 B 。

    就好像使用模块的时候,你不用担心不同模块之间的全局变量相互影响一样,采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。

    这样不同的作者都可以提供 NumPy 模块,或者是 Python 图形库。

    包的创建

    创建包会自动生成__init__.py文件

    ![1561980301880](file:///C:/Users/86131/AppData/Roaming/Typora/typora-user-images/1561980301880.png)

    回忆 创建一个tbjx模块发生的三件事:
    将该tbjx文件加载到内存.
    创建一个以tbjx命名的名称空间.
    通过tbjx. 的方式引用tbjx模块的所有的名字.
    
    创建一个包,也会发生三件事:
    将该aaa包内 __init__py文件加载到内存.
    创建一个以aaa命名的名称空间.
    通过aaa. 的方式引用__init__的所有的名字.
    包名就是 幕后指使的 init执行
    

    包的引用方式

    import 方式导入

    aaa包与执行文件同级的情况
    引用aaa包的__init__中的name
    import aaa
    print(aaa.name)#因为执行aaa 其实就是执行__inint__中内容
    
    
    # 我想要引用 aaa包的m1文件的a变量
    # 错误示例1:
    import aaa
    # 1. aaa的 __init__ 里面 写import m1
    # 2. print(aaa.m1.a)
    # print(aaa.m1.a)
    # 报错原因: No module named 'm1'
    # 分析报错原因: 模块找不到 内存,内置,sys.path三个地方找不到.
    # m1 不在内存,不在内置,sys.path  会主动加载执行文件(包的使用.py)的当前目录. 而他不在
    
    # 解决方式:
    import aaa
    # 1. 在执行文件写入 import aaa
    # 2. aaa的 __init__ 里面 写 from aaa import m1#m1是要引入的文件名 aaa是包名
    # 3. 然后在执行文件  aaa.m1.a
    # print(aaa.m1.a) 引用 aaa包的m1的a
    # print(aaa.m1.func1())#引用 aaa包的m1的func1()
    
    
    # 如何在当前文件中,引用 aaa包的bbb包中__init__中 name.
    # 1. 在执行文件写入 import aaa
    # 2. aaa的 __init__ 里面 写 from aaa import bbb
    # 3. 然后在执行文件 print(aaa.bbb.name)
    
    
    # 如何在当前文件中,引用 aaa包的bbb包 a1.py文件中的 name
    # 1. 在执行文件写入 import aaa
    # 2. 在aaa包的__Init__ 写上 from aaa import bbb  (这样写 bbb包的__init__里面所有的名字都能引用)
    # 3. 在bbb包的__Init__ 写上 from aaa.bbb import mb
    4 print(aaa.bbb.a1.name)
    
    
    # 首先 无论从哪里引用模块,import 或者 from  ... import ...
    # 最开始的模块或者包名一定是内存,内置,sys.path中能找到的.(可参考bbb包中的 __init__)
    # 直接import 为了让我们会使用 包里面的 __init__
    

    from方式导入

    # 第二类: 执行文件 通过 from ... import... 导入包以及包内的功能
    # from ... import ...
    # 通过这种方式不用设置__init__文件
    
    我想要引用 aaa包的__init__ name
    from aaa import name
    print(name)
    
    我想要引用 aaa包的 a1 文件中name
    from aaa import a1
    print(a1.name)
    
    我想要引用 aaa包的 bbb包 __init__ name
    from aaa.bbb import name
    print(name)
    
    我想要引用 aaa包的 bbb包 a1文件的中的name
    from aaa.bbb import a1
    print(a1.name)
    
    
    
    重点
    # from a.b.c import d
    # c的. 的前面一定是包 
    # import 的后面一定是名字 可以是文件,  并且不能 再有点   不能有点
    
    # from aaa.bbb.m2.func1 import a  # 错误的
    # from aaa.bbb import m2
    # m2.func1()
    

    相对导入与绝对导入

    # from nb.m1 import f1,f2
    
    # from nb.m2 import f3,f4
    
    # from nb.m3 import f5,f6
    
    # 目前为止,今天所看到的引用模块的方式都是绝对导入
    
    
    # 相对导入: . ..  ......
    
    from .m1 import f1,f2
    
    from .m2 import f3,f4
    
    from .m3 import f5,f6
    
    from .dsb.ly import f7
    需求
    # 由于nb模块增加了很多很多功能,所以我们nb这个文件就要划整一个包,
    # 无论对nb模块有任何操作,对于使用者来说不应该改变,极少的改变对其的调用. 像装饰器
    第一版 文件变成包了 包与执行文件 在同一目录  
     用户 使用方式
    # import nb
    # nb.f1()
    # nb.f2()
    我们的解决方式 在aaa包的__init__ 加入
    from nb.m1 import f1,f2#m1 中有f1 f2
    from nb.m2 import f3,f4
    from nb.m3 import f5,f6
    
    第2版 包与 执行文件 不在同一文件 要想运行 必须在执行文件 添加sys 路径
    import sys
    sys.path.append(r'D:python22python 23 代码day19相对导入第2版 包在另一个文件下dir') #写死了 可以动态传
    
    第3版 模块改名
    在__init__ 里面改成相对导入
    from .m1 import f1,f2#当前目录上一级
    from .m2 import f3,f4
    from .m3 import f5,f6
    
    from .. import settings
    
  • 相关阅读:
    二分查找总结
    多线程之Timer和TimerTask
    多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition
    java多线程之Callable、Future和FutureTask
    多线程之CountDownLatch、CyclicBarrier和Semaphore
    多线程之线程池的使用
    多线程之阻塞队列
    Transient关键字的使用
    多线程并发容器CopyOnWriteArrayList
    AtomicInteger学习
  • 原文地址:https://www.cnblogs.com/saoqiang/p/12176913.html
Copyright © 2011-2022 走看看