• day15-模块的基础及导入


    模块

    什么是模块

    函数是某一功能的集合体,而模块是一系列功能的集合体,因此模块可以看成是一堆函数的集合体。一个py文件内部就可以放一堆函数,因此一个py文件就可以看成是一个模块,如果文件名为module.py,则模块名为module。模块分为以下几类:

    • 自定义模块:即使用python编写的.py文件
    • 第三方模块:已被编译为共享库或DLL的C或C++扩展,需要自己下载,如requests
    • 内置模块:使用C编写并链接到python解释器的内置模块,直接用就行了,如time
    • 包:把一系列模块组织到一起的文件夹,并有一个_init_.py文件

    使用模块

    我们一般使用import和from...import导入模块。导入模块时将文件执行一遍

    import

    在用import模块导入时发生了以下几件事(如import time):

    1. 打开time文件
    2. 把time文件内的内容读入python解释器的内存,然后把文件内的名字放入特定的模块time的名称空间
    3. 在使用time.sleep(1)这个方法的时候,回去time模块的名称空间内部寻找time的方法
    4. 然后直接使用time.sleep(1)就行了

    想比用from...import...而言

    • 优点:模块里的方法和变量都能拿到使用
    • 缺点:占用内存比较大,在使用时必须得通过模块名.方法()使用

    from ... import ...

    在用from...import模块导入时发生了以下几件事(如from time import sleep):

    1. 打开time文件
    2. 把time文件内的内容读入到python解释器的内存,然后把文件内的名字放入到特定的模块time的名称空间内
    3. 把sleep单独拿出来放入import与from....import.py的名称空间中去
    4. 然后直接使用sleep(1)就可以了

    相比较import而言

    • 优点:直接使用方法()就行了
    • 缺点:只能拿到单独的某个方法,并且若文件中定义了sleep参数,在使用时会冲突
    import time    # 导入time模块
    time.sleep(3)
    
    from time import sleep    # 导入time模块中的某个方法
    from time import sleep,time    # 导入模块中的sleep和time方法
    from time import *    # 导入模块time
    sleep(3)
    
    import time as t	# 相当于给time模块取别名
    t.sleep(3)		# 正确
    time.sleep(3)	# 错误
    

    循环导入问题

    有m1和m2两个文件,然后m1需要找到m2的y,m2需要找到m1的x。但是由于代码自上而下运行,m1中的x还没有生成,m2中的y也没有生成,所以m1找不到m2的y;m2找不到m1的x,就造成了一个死循环

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

    解决方案一

    在导入之前让变量提前生成

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

    在运行m1.py文件时,会执行两次打印。将m2中的print(x)打印出来,结果并不是我们想要的;其次若变量多个时,不方便使用

    解决方案二

    把需要导入的名字封装到函数体内部。由于名字的执行顺序是:内置—>全局—>局部。在调用函数之前,全局变量已经生成了,m2能找到x,y就能够生成,问题就解决了

    # m1.py
    def func1():
        x = 10
        from m2 import y
        print(y)
    
    # m2.py
    def func2():
        y = 20
        from m1 import x
        print(x)
        
    func1()
    

    模块的搜索路径

    • 先搜索内存中有的:运行过的模块
    • 再搜索内置模块中的模块
    • 最后搜索环境变量中的模块

    Python文件的两种用途

    模块文件:当做模块导入

    运行文件:当做文件运行

    包是自带_init_.py文件的文件,包也是模块。包在被导入的时候发生三件事(如导入包test):

    1. 创建一个包的名称空间,打开test里的_init_.py文件
    2. Python解释器运行解释__init__.py文件,把__init__.py里的名字丢入到包的名称空间内
    3. 导入包其实就是导入包下的__init__.py。并且可以通过import... 和from...import...就行导入

    导入包内包

    aaa.bbb指向aaa内部的文件夹bbb包,如果我们需要导入bbb这个包

    # aaa/__init__.py
    from aaa import bbb
    
    # run.py
    import aaa
    print(aaa.bbb)
    

    导入包内包的模块

    如果bbb包内有m1.py文件,我们需要在run.py内导入m3模块

    # aaa/__init__.py
    from aaa.bbb import m3
    
    # run.py
    import aaa
    aaa.bbb.m3
    

    绝对导入与相对导入

    绝对导入

    # aaa/__init__.py
    from aaa.m1 import func1
    from aaa.m2 import func2
    

    相对导入

    from .m1 import func1
    
    • . 代表当前被导入文件所在的文件夹
    • .. 代表当前被导入文件所在文件夹的上一级
    • ... 代表当前被导入文件所在的文件夹的上一级的上一级

    注意事项:. 号前面必须得是一个包,不能是一个模块;当文件是执行文件时,不能用相对导入;包内所有的文件都是被导入使用的,而不是被直接运行的

  • 相关阅读:
    kill命令
    linux grep命令
    ps命令详解
    Linux chmod命令详解
    Linux netstat命令详解
    多线程同步机制的几种方法
    C++_运算符重载 总结
    malloc/free与new/delete的区别
    python发送邮件
    linux之nfs
  • 原文地址:https://www.cnblogs.com/863652104kai/p/10994551.html
Copyright © 2020-2023  润新知