• 模块


    从普通的面条型代码,到函数型代码,其实是在做什么?

    1. 封装代码,一个函数差不多2-40行代码,实现一个小功能
    2. 让不同功能的代码独立开来

    代码发展史:

    面条版 --》函数版--》文件版--》文件夹版--》微服务(把大的项目拆分成多个小项目)

    而文件版,在Python中叫做模块

    • 为什么要有模块?

    • 模块可以放很多个函数,然后把大量的函数分割成多个文件,每一个模块都具有很大的功能

    模块

    • 模块就是拿来主义,简化操作,让我们不要进行重复开发相同的功能

    模块的分类

    1. 自定义模块,自己写的
    2. 第三方库,需要自己去下载,如requests
    3. 内置模块,直接用就行了,如time
    4. 文件夹版,在Python中叫做包

    一般使用import和from...import...导入模块

    # spam.py
    print('welcome to spam.py')
    
    def f1():
        print('from f1')
    

    import 与 from...import

    # test.py
    import time 
    
    1. 打开time文件
    2. 使用Python解释器运行time文件,然后把解释文件内的名字放入模块time的名称空间,会运行文件中所有的代码
    3. test.py中会有一个time变量指向time模块的名称空间,如果导入方式为`import time as t`,则是t变量指向time模块的名称空间
    * 指向整个time文件,会把整个time文件都放入内存空间中,要用什么拿什么
    优点:time里面有的方法全部拿出来
    缺点:占用内存比较大,必须得通过time.出来
    
    # test.py
    
    from time import sleep
    
    1. 打开time文件
    2. 使用Python解释器运行time文件,然后把解释文件得到的名字放入time模块的名称空间,**同样运行所有的代码**
    3. test.py中会有sleep变量指向time模块名称空间中的sleep,如果导入方式为`from time import sleep, localtime`,则是有一个sleep变量和一个locatime变量指向time模块名称空间中的sleep和localtime.
    	`from time import *`同理,是有time中所有名字的变量,可以在模块文件中使用`__all__`控制会被*导入的函数
        
    * 变量名直接指向A中的方法名,并没有指向A,是去A中把f1拿出来
    * 一个是拿他的东西,另一个是拿他的店
    优点:直接使用sleep就可以了
    缺点:只能拿到sleep,如果该文件定义了sleep参数,则会冲突
    
    ### 导入多个模块
    import spam, time, os
    
    推荐下面的方法
    import spam
    import time
    import os
    

    循环导入问题

    • 两个文件互相查找
    # m1.py
    from m2 import y
    x = 1
    print(y)
    
    # m2.py
    from m1 import x
    y = 2
    print(x)
    

    为什么会有循环导入问题

    1. 代码自上而下运行,m1需要m2的y,所以会去m2的名称空间中找y,但是在找y前,会运行m2的代码
    2. 而m2的代码第一句又是去找m1的x,所以就冲突报错了
    3. 也就是说m1和m2都只是运行了第一行,就出现了循环导入问题

    解决方案一

    # m1.py
    x = 10
    from m2 import y
    print(y)
    
    # m2.py
    y = 20
    from m1 import x
    print(x)
    
    • 但是这样做,很复杂,并且需要提前定义,得到的结果也并非是我们想要的,治标不治本

    解决方案二

    # m1.py
    def f1():
        from m2 import y
        print(y)
    x = 1
    
    f1()
    
    
    # m2.py
    def f2():
        from m1 import x
        print(x)
    y = 2
    
    
    f2()
    
    • 利用的是名字的执行(定义)顺序:内置(Python解释器启动的时候)--》全局(文件执行的时候)--》局部(函数调用的时候)
    • 利用局部名称永远在全局名称后定义的原理,在调用函数前,变量已经被定义好了

    模块的搜索路径

    1.去内存中找

    # test.py
    import m1 # 从m1.py文件中导入的,然后会生成m1模块的名称空间
    import time
    
    # 删除m1.py文件,m1模块的名称空间仍然存在
    
    time.sleep(10)
    
    import m1  # 不报错,一定不是从文件中获取了m1模块,而是从内存中获取的
    

    2.去内置模块中找

    # time.py
    print('from time')
    
    # test.py
    import time  # 无任何打印,所以他先去内置模块中找了
    

    3.去环境变量中找

    import sys
    
    print(sys.path)     # 打印当前父目录下环境变量中的包
    
    # b/a/m1.py
    # b/test.py
    
    import m1   # 报错
    
    sys.path.append('b/a')  # 把这个目录添加到环境变量中
    import m1
    

    Python文件的两种用途

    1. 模块文件,被当做模块给导入,有多个
    2. 运行文件,被当做执行文件执行,只能有一个
    • 搜索路径以执行文件为基准
    # m1.py
    def f1():
        print('from f1')
        
    f1()
    
    # test.py
    import m1
    
    m1.f1()      # 运行两次
    
    • _name_
    # m1.py
    def f1():
        print('from f1')
        
    if __name__ == '__main__':  # __name__在m1.py被当做模块导入时是模块名,作为执行文件执行是'__main__'
        f1()
        
        
    # test.py
    import m1
    
    m1.f1()     # 运行一次
    
  • 相关阅读:
    Java—异常处理总结
    CSS white-space 属性
    兼容性问题的总结
    学习利用vertical-align:middle实现在整个页面居中
    多口USB HUB信号延长器 USBX-M200(针对于A客户使用时很棒吧)
    凌华运动控制卡调试记录
    记录:EPALN Electric P8 2.4.4.8366 安装记录
    一步一步创建一个动态库
    (转)VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径说明
    凌华运动控制卡的函数。
  • 原文地址:https://www.cnblogs.com/lucky75/p/10981263.html
Copyright © 2020-2023  润新知