zoukankan      html  css  js  c++  java
  • 模块及模块导入

    今日学习内容:

    模块

    import以及from...import...

    循环导入、相对导入、绝对导入

    模块

    什么是模块?

    模块:就是一系列功能的结合体。

    三种来源:

    1.内置的(python解释器自带)

    2.第三方的(别人写的)

    3.自定义的(你自己的写)

    四种表现形式:

    1.使用python编写的py文件(也就意味着py文件也可以称之为模块:一个py文件也可以称之为一个模块)

    2.已被编译为共享库或DLL的C或C++扩展(了解)

    3.把一系列模块组织到一起的文件夹(文件夹下有一个init.py文件,该文件夹称之为包(一系列py文件的结合体))

    4.使用C编写并连接到python解释器的内置模块

    为什么要用模块?

    1.用别人写好的模块(内置的,等三方的)拿来主义,极大的提高开发效率。

    2.使用自己写的模块(自定义的):当程序比较庞大时,你的项目不可能只在一个py文件中,当多个py文件都需要使用相同的方法时,可以将该方法写一个py文件里,让其它文件以模块形式导过去调用即可。

    如何使用模块?

    需要用到import和 from...import...进行导入

    注意:一定要区分那个是执行文件,哪个是被导入文件。

    import

    我们先创建两个py文件,run.py和md.py

    #mad.py
    #我们随意输入一点内容
    print('from the md.py')
    money=1000
    def read1():
        print('md',money)
    def read2():
        print('md模块')
        read1()
    def change():
        global money
        money = 0
    #run.py
    import md
    #右键运行run.py文件首先会创建一个run.py的名称空间
    #首次导入模块(md.py)
    #1、创建md.py文件名称空间
    #2、运行md.py文件中的代码,将产生的名字与值存放到md.py名称空间中
    #3、在执行文件中拿到一个指向名称空间的名字(md)
    #补充:多次导入不会再执行模块代码,会沿用第一次导入的成果。(***)
    
    money = 9999
    
    print(md.money)  # 输出1000
    print(money)  # 输出9999
    
    def read1():
        print('from run read1')
    
    read1()  # 输出结果为from run read1
    md.read1()  # 输出结果为md 1000
    # 使用import导入模块 访问模块名称空间中的名字统一句势:模块名.名字

    运行在内存空间中的示意图

    使用import导入模块 访问模块名称空间中的名字统一句势:模块名.名字,如md.money
    1.指名道姓的访问模块中的名字 永远不会与执行文件中的名字冲突
    2.你如果想访问模块中名字 必须用模块名.名字的方式

    只要当几个模块有相同部分或者属于用一个模块,可以使用上面的方法
    当几个模块没有联系的情况下 应该分多次导入
    import os
    import time
    import md
    ps:通常导入模块的句式会写在文件的开头

    #当模块名字比较复杂的情况下,可以给该模块名取个别名:
    #格式为
    import 模块名 as 别名
    #访问模块中名字的时候就是将原来的模块名.名字变成别名.名字就可以了

    from...import...

    #和上面一样,我们同样先创建两个文件run1和md1
    #然后是运行run1.py
    #首次导入run1.py模块
    #1、创建md1.py文件名称空间
    #2、运行md1.py文件内的代码,将产生的名字存放到md1.py名称空间中
    #3、在执行文件中拿到一个名字,该名字直接指向md1.py名称空间中的某个名字(和上面不同的点)
    
    
    #利用from...import...句式
    #缺点:
    #    1、访问模块中的名字不需要加模块名前缀
    #    2、在访问模块中的名字可能会与当前执行文件中的名字冲突
    # 补充
    from md1 import *  # 一次性将md1模块中的名字全部加载过来 不推荐使用 并且你根本不知道到底有哪些名字可以用
    #以md1.py为例
    __all__ = ['money','read1','read2']  # 也可以限制导入者能够拿到的名字个数
    
    __all__ = ['','','']  当__all__所在的文件被当做模块导入的时候
    ___all__列表写什么 执行导入语句那个文件就能拿到什么
    __all__不写的情况下 默认是将所在文件所有的名字都暴露给导入者

    __name__的使用

    #m1文件内容
    def index1():
        print('index1')
    
    def index2():
        print('index2')
    
    print(__name__)
    
    #m2文件内容
    import m1
    
    
    #m1打印结果__main__
    #m2打印结果m1
    
    #当文件被当做执行文件执行时__name__打印的结果是__main__
    #当文件被当做模块导入的时候__name__打印的结果是模块名(没有后缀)
    
    #if __name__ == '__main__: # 把它添加到被调用模块中,当该模块被调用时,后面的语句不会执行
    
    #if __name__ == '__main__':  # 快捷写法,main直接tab键即可

    循环导入

    #创建3个py文件,m1.py、m2.py、run.py
    
    #m1的内容
    print('正在导入m1')
    from m2 import y
    
    x = 'm1'
    
    #m2的内容
    print('正在导入m2')
    from m1 import x
    
    y = 'm2'
    
    #run的内容
    import m1
    
    #运行结果是报错cannot import name 'x'
    #分析运行过程:运行run之后,首先会导入m1,然后我们执行m1,执行m1会打印“正在导入m1”这句话,然后根据下一句话会调用到m2,然后执行m2,然后打印正在导入m2,然后执行第三句话,需要从m1中拿到x,但此时m1中并没有执行到给x赋值的阶段,所以相当于x没有定义,所以出现了错误

    如果出现循环导入问题,那么一定是你的程序设计的不合理,循环导入问题应该在程序设计阶段就应该避免。

    解决循环导入问题的方式:

    方式1:将循环导入的句式写在文件最下方

    方式2:函数内导入模块

    方式3:将循环导入的名字 放到另外一个文件中

    模块的查找顺序

    1、先从内存中找(被你自己导入的)

    2、内置中找(python解释器自带的)

    3、sys.path中找(环境变量):

        一定要分清楚谁是执行文件谁是被导入文件(****)

    import sys
    print(sys.path)  # 可以看到文件路径。是一个大列表,里面放了一对文件路径,第一个路径永远是执行文件所在的文件夹
    sys.path.append()  # 括号里可以添加文件路径
    #第一种导入:基于当前执行文件所在文件夹路径依次往下找
    #第二种导入:直接将你需要导入的那个模块所在的文件夹路径添加到system path中
    
    

    绝对导入和相对导入

    绝对导入必须依据执行文件所在的文件夹路径为准
    绝对导入无论在执行文件中还是被导入文件都适用

    相对导入
    .代表的当前路径
    ..代表的上一级路径
    ...代表的是上上一级路径

    注意相对导入不能再执行文件中使用
    相对导入只能在被导入的模块中使用,使用相对导入 就不需要考虑
    执行文件到底是谁 只需要知道模块与模块之间路径关系

  • 相关阅读:
    kafka学习笔记(六)kafka的controller模块
    腾讯蓝鲸使用笔记
    kafka学习笔记(五)kafka的请求处理模块
    kafka学习笔记(四)kafka的日志模块
    kafka学习笔记(三)kafka的使用技巧
    kafka学习笔记(二)kafka的基本使用
    kafka学习笔记(一)消息队列和kafka入门
    大数据安全与RANGER学习和使用
    10-Linux 基本指令
    09-迭代器、模块
  • 原文地址:https://www.cnblogs.com/wangnanfei/p/11196896.html
Copyright © 2011-2022 走看看