zoukankan      html  css  js  c++  java
  • 第三十二篇 模块

    一、为什么要有模块

    1.模块的好处:

    代码封装到模块中,代码会变得更加简洁,清晰,模块化,使用更高效,维护更方便,减少代码重复率

    2.代码格式变化的流程:

    我们写的代码从最开始的: 面条版代码--》函数版代码--》文件版代码(模块)--》文件夹版(包),这个进阶过程,让我们的代码更加美观、逻辑性更强、维护更方便

    3.模块的本质:

    一个模块里会有多个函数,相当于一个大功能细分成多个小功能

    4.模块的分类:

    1. 自定义模块:自己写的许多函数,放入一个py文件中

    2. 第三方模块:别人写好的 模块,需要下载,如requests

    3. 内置模块:python解释器自带的模块,如time

    4. 包(文件夹):本质上也是模块,只是将多个模块放入一个文件夹中(python package)

    二、import 与 from...import...

    1. import

    # test.py    # 执行文件中
    
    import time 
    
    1. 打开time文件
    2. 使用Python解释器运行time文件,然后把解释文件得到的名字放入time模块的名称空间
    3. test.py中会有一个time变量指向time模块的名称空间,如果导入方式为`import time as t`,则就是t变量指向time模块的名称空间
    

    2.from...import...

    # test.py     # 执行文件test.py中
    from time import sleep
    
    1. 打开time文件
    2. 使用Python解释器运行time文件,然后把解释文件得到的名字放入time模块的名称空间
    3. test.py中会有一个sleep变量指向time模块名称空间中的sleep,如果导入方式为`from time import sleep,localtime`,则是由一个sleep变量和一个localtime变量指向time模块名称空间中的sleep和localtime
    

    3.import...as...

    # test.py
    import time as t   # 其实就是用另一个变量代替time来引用模块
    t.sleep(2)        # 以前是time.sleep(2),只是变量名不同而已
    
    

    三、循环导入问题

    # m1.py
    from m2 import y
    x = 10
    
    # m2.py
    from m1 import x
    y = 20
    

    1.为什么会有循环导入问题:

    1. m1文件需要导入m2文件的y
    2. m2文件需要导入m1文件的x
    3. 代码自上而下运行,m1需要m2的y,然后会去m2的名称空间找到y,但是找y前,需要运行m2的代码,m2的代码第一句是去找m1的x,然后又回去运行m1的代码,m1的第一行代码又是去寻找m2的y
    4. 就是说m1只能运行第一行,m2也只能运行第一行,所以出现了循环导入问题

    2.解决方案一

    1.方法:将需要导入的模块放在最前面

    2.效果:但是这样做,对所有的变量都需要这样做,才能解决问题,所以治标不治本的

    # m1.py
    x = 10
    from m2 import y
    
    
    # m2.py
    y = 20
    from m1 import x
    
    

    3. 解决方案二

    1.方法:将导入模块的方法写成函数,利用名称空间执行的顺序的特质来实现

    2.内部逻辑:名字的执行顺序:内置(python解释器启动的时候)-->全局(文件执行的时候)-->局部(函数调用的时候)

    # m1.py
    def f1():
        from m2 import y
    x = 10
    
    
    f1()
    
    
    # m2.py
    def f2():
    	from m1 import x
    y = 20
    
    
    f2()
    

    四、模块的搜索路径

    1.程序最先会去内存中找

    之前导入过的模块在程序没有关闭时,会一直存在内存中,所以可以在内存中找到导入过的模块

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

    2.程序然后再去内置模块中找

    内存中没有我们想要的模块,程序会去python自带的模块中去找(如果自定义模块与内置模块重名,会优先选择内置模块)

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

    3.最后才会去环境变量中找

    所有的查找都是通过路径,也就是环境变量,所以如果找不到,可以找到目标模块的路径,然后添加到查找路径中的根路径上

    import sys
    
    print(sys.path)  # 当前文件的根路径
    """
    ['B:\ATM', 'B:\ATM', 'F:\python3.0\python36.zip', 'F:\python3.0\DLLs', 'F:\python3.0\lib', 'F:\python3.0', 'F:\python3.0\lib\site-packages', 'F:\PyCharm 2018.1.4\helpers\pycharm_matplotlib_backend']
    """
    # 第一个就是当前文件的路径,后面一个是当前文件所在的最开始的文件的路径(它是固定不变的,无论是哪个文件,只要是在这个文件夹中)
    
    # b/a/m1.py
    
    # b/test.py
    import m1  # 报错。在b文件中只能找到同级目录下的a文件
    
    sys.path.append('b/a')
    import m1
    

    五、Python文件的两种用途

    1. 模块文件:

    .py文件可以被当做模块给导入,可以有许多个模块文件,也就是说可以在执行文件中导入它们,并且可以导入多个模块

    2. 运行文件:

    1.被当做执行文件执行,只能有一个,也就是说 .py文件当作执行文件时,必须是在一个文件下运行,才能执行出想要的结果

    3.模块的搜索路径:

    以执行文件为基准

    # m1.py  # 模块1文件
    def f1():
        print('from f1')
        
    f1()  # 模块1文件中的函数调用
    
    # test.py   # 执行文件
    import m1
    
    m1.f1()  # 由于在导入模块1文件时,它除了开辟空间放入名字,还会运行它里面的可执行程序,所以导入执行文件之后,运行模块1中的函数时会出现运行两次的现象
    

    可以用__name__ == 'main'解决(如果被导入模块中有可执行函数时,必须将这个条件语句放在被导入模块中进行过滤)

    # m1.py
    def f1():
        print('from f1')
        
    if __name__ == '__main__':  # __name__在m1.py被当做模块导入时是模块名,作为执行文件时是'__main__'
        f1()        # 这个条件语句也就是说如果当m1.py文件被当作执行文件时,f1()函数就是可执行的;否则当m1.py文件被当作模块文件被导入到其他执行文件中时,f1()函数也和其他名字一样当作模块名被导入,不会执行
        
    
    # test.py
    import m1
    
    m1.f1()  # 运行一次
    
  • 相关阅读:
    我的Android学习路线(二)
    利用python3.x实现小爬虫下载贴吧内图片
    我的Android学习路线(一)
    根网科技面试题
    sql语句的执行顺序
    英文面试常见问题汇总
    关于oracle、sqlserver、mysql查询前N条数据的实现
    LinqToSql(一)
    关于一些概念的问题,命名空间,程序集,解决方案,项目
    索引器
  • 原文地址:https://www.cnblogs.com/itboy-newking/p/11038821.html
Copyright © 2011-2022 走看看