zoukankan      html  css  js  c++  java
  • 模块

    模块

    1 什么是模块
        模块就是一系列功能的集合体
            模块有三种来源
                1. 内置的模块
                2. 第三方的模块
                3. 自定义模块
            模块的格式:
                1 使用python编写的.py文件
              2 已被编译为共享库或DLL的C或C++扩展
              3 把一系列模块组织到一起的文件夹(注:文件夹下有一个__init__.py文件,该文件夹称之为包)
              4 使用C编写并链接到python解释器的内置模块
    
    2 为何要用模块
        1. 使用内置的或者第三方模块的好处是: 拿来主义,可以极大提升开发效率
        2. 使用自定义模块的好处是: 可以减少代码冗余(抽取我们自己程序中要公用的一些功能定义成模块,然后程序的各部分组件都去模块中调用共享的功能)
    
    3 如何用模块
        大前提: 一定要区分开谁是执行文件,谁是被导入模块
    

    import导入模块

    # spam.py
    print('from the spam.py')
    money=1000
    def read1():
        print('spam模块:',money)
    def read2():
        print('spam模块')
        read1()
    def change():
        global money
        money=0
        
    # 文件名是spam.py,模块名则是spam
    # 首次导入模块发生3件事
    # 1. 会产生一个模块的名称空间
    # 2. 执行文件spam.py,将执行过程中产生的名字都放到模块的名称空间中
    # 3. 在当前执行文件的名称空间中拿到一个模块名,该名字指向模块的名称空间
    import spam
    # 之后的导入,都是直接引用第一次导入的成果,不会重新执行文件
    import spam
    import spam
    import spam
    import spam
    
    # 在执行文件中访问模块名称空间中名字的语法:模块名.名字
    import spam
    
    print(spam.x) # 指名道姓地跟spam要名字x,肯定不会与当前执行文件中的名字冲突
    
    x # 向当前执行文件的名称空间要名字
    
    money=11111111111111111111111
    print(spam.money)
    print(spam.read1)
    print(spam.read2)
    print(spam.change)
    spam.read1()
    def read1():
        print('run.py --> read1')
    spam.read2()
    spam.change()
    print(spam.money)
    print(money)
    # 总结import导入模块:在使用时必须加上前缀:模块名.
    # 优点: 指名道姓地向某一个名称空间要名字,肯定不会与当前名称空间中的名字冲突
    # 缺点: 但凡应用模块中的名字都需要加前缀,不够简洁
    
    # 一行导入多个模块(不推荐)
    import spam,os,time
    # 可以为模块起别名(注意:模块名应该全为小写)
    import spam as sm
    print(sm.money)
    print(sm.read1)
    
    

    from...import...导入模块

    # spam.py
    print('from the spam.py')
    __all__ = ['money','read1'] #from spam import *
    money=1000
    def read1():
        print('spam模块:',money)
    def read2():
        print('spam模块')
        read1()
    def change():
        global money
        money=0
      
    
    money=200
    # 首次导入模块发生3件事
    # 1. 创建一个模块的名称空间
    # 2. 执行文件spam.py,将执行过程中产生的名字都放到模块的名称空间中
    # 3. 在当前执行文件中直接拿到一个名字,该名字就是执行模块中相对应的名字的
    from spam import money,read1,read2,change
    money=200
    print(money)
    
    read1=123
    read1()
    read2()
    
    change()
    print(money)
    
    # 总结from...import...
    # 优点: 使用时,无需再加前缀,更简洁
    # 缺点: 容易与当前名称空间中的名字冲突
    
    # *代表从被导入模块中拿到所有名字(不推荐使用)
    from spam import money,read1,read2,change
    from spam import * # __all__ = ['money','read1']
    print(money)
    print(read1)
    print(read2)
    print(change)
    
    # 起别名
    from spam import read1 as r1
    r1()
    

    模块的循环导入

    # m1.py   # 模块一
    # 错误示范
    '''
    print('正在导入m1')
    from m2 import y #第一次导入m2
    x='m1'
    '''
    
    # 解决方案一: 把循环导入的语句放到名字定义的后面
    print('正在导入m1')
    x='m1'
    from m2 import y #第一次导入m2
    
    # 解决方案二: 将循环导入语句放到函数内
    print('正在导入m1')
    def f1():
        from m2 import y,f2 #第一次导入m2
        print('m1.f1---->y: ',y)
        f2()
    x='m1'
    
    
    # m2.py   # 模块二
    # 错误示范
    '''
    print('正在导入m2')
    from m1 import x
    y='m2'
    '''
    # 解决方案一: 把循环导入的语句放到名字定义的后面
    print('正在导入m2')
    y='m2'
    from m1 import x
    
    # 解决方案二: 将循环导入语句放到函数内
    print('正在导入m2')
    def f2():
        from m1 import x
        print('m2.f2--->x: ',x)
    y='m2'
    
    
    # run.py   # 运行主程序
    # import m1 # 第一次导入
    
    # 验证解决方案一:把循环导入的语句放到名字定义的后面
    '''
    正在导入m1
    正在导入m2
    '''
    # print(m1.x)
    # print(m1.y)
    
    # 验证解决方案二:将循环导入语句放到函数内
    import m1 # 第一次导入
    '''
    正在导入m1
    '''
    # print(m1.x)
    # print(m1.f1)
    m1.f1()
    '''
    正在导入m2
    m1.f1---->y:m2
    m2.f2--->x:m1
    '''
    

    区分python文件的两种用途

    # 当文件被执行时:__name__=='__main__'
    # 当文件被导入时:__name__=='模块名'
    
    # m1.py
    def f1():
        print('f1')
    def f2():
        print('f2')
        
    print(__name__)
    if __name__ == '__main__':
        f1()
        f2()
    # 运行结果:
    # __main__
    # f1
    # f2
    
    # run.py
    import m1   # 运行结果:m1
    

    模块的搜索路径

    # 模块搜索路径的优先级
    # 1. 内存中已经加载过的
    # 2. 内置模块
    # 3. sys.path #  第一个值是当前执行文件所在的文件夹
    import sys
    print(sys.path)  # 打印当前运行文件路径并向上层寻找的文件夹名列表
    
    # 如果无法导入模块(原因是在路径中没有搜索到),有两种解决方案:
    # 方案一:
    import sys
    sys.path.append(r'D:documentpythonegon视频day16代码3 模块的搜索路径1dir1')
    print(sys.path)
    import m1
    m1.f1()
    
    # 方案二:
    from dir1 import m1 # 寻找一层
    m1.f1()
    from dir1.dir2 import m2 # 寻找两层
    m2.f2()
    
    
    # m2.py
    def f2():
        print('m2.f2')
        
    # m1.py
    import m2
    from dir1 import m2 # 所有被导入的模块再去导入其他模块,参考的都是执行文件的sys.path
    def f1():
        print('from f1')
        m2.f2()
     
    # run.py
    # 环境变量是以当前执行文件为准的
    # ******强调:所有被导入的模块参照环境变量sys.path都是以执行文件为准的
    import sys
    sys.path.append(r'D:脱产三期视频day164 模块的搜索路径2dir0')
    from dir1 import m1 # 从列表中的第一个文件开始找dir1
    m1.f1()
    

    绝对导入和相对导入

    # 绝对导入: 以执行文件的sys.path为起始点开始导入,称之为绝对导入
    #        优点: 执行文件与被导入的模块中都可以使用
    #        缺点: 所有导入都是以sys.path为起始点,导入麻烦
    
    # 相对导入: 参照当前所在文件的文件夹为起始开始查找,称之为相对导入
    #        符号: .代表当前所在文件的文件加,..代表上一级文件夹,...代表上一级的上一级文件夹
    #        优点: 导入更加简单
    #        缺点: 只能在导入包中的模块时才能使用,不能在执行文件中用
    
    # 执行文件中只能用绝对导入
    

    time 模块

    """
        time模块
            与时间相关的功能
        在python中 时间分为3种
            1.时间戳  timestamp  从1970 1 月 1日 到先在的秒数  主要用于计算两个时间的差
            2.localtime  本地时间  表示的是计算机当前所在的位置
            3.UTC 世界协调时间
              时间戳 结构化 格式化字符
    """
    import time
    
    # 获取时间戳  返回浮点型
    print(time.time())
    
    # 获取当地时间   返回的是结构化时间
    print(time.localtime())
    
    #  获取UTC时间 返回的还是结构化时间  比中国时间少8小时
    print(time.gmtime())
    
    # 将获取的时间转成我们期望的格式 仅支持结构化时间
    print(time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
    
    # 将格式化字符串的时间转为结构化时间  注意 格式必须匹配
    print(time.strptime("2018-08-09 09:01:22","%Y-%m-%d %H:%M:%S"))
    
    # 时间戳 转结构化
    print(time.localtime(time.time()))
    
    # 结构化转 时间戳
    print(time.mktime(time.localtime()))
    
    # sleep 让当前进程睡眠一段时间 单位是秒
    # time.sleep(2)
    # print("over")
    
    # 不太常用的时间格式
    print(time.asctime())
    print(time.ctime())
    

    datetime 模块

    """
        datetime
            python实现的一个时间处理模块
        time 用起来不太方便  所以就有了datetme
        总结 datetime相比time 更灵活 更本土化
    
        timedelta表示时间差
            两个时间差可以 +-*/
            时间差和datetime 可以+-
    """
    import datetime
    
    # 获取时间 获取当前时间 并且返回的是格式化字符时间
    print(datetime.datetime.now())
    
    # 单独获取某个时间 年 月
    d = datetime.datetime.now()
    print(d.year)
    print(d.day)
    
    # 手动指定时间
    d2 = datetime.datetime(2018,8,9,9,50,00)
    print(d2)
    
    # 计算两个时间的差  只能- 不能加+
    print(d - d2)
    
    # 替换某个时间
    print(d.replace(year=2020))
    
    # 表示时间差的模块 timedelta
    print(datetime.timedelta(days=1))
    
    t1 = datetime.timedelta(days=1)
    t2 = datetime.timedelta(weeks=1)
    print(t2 - t1)
    # 时间差可以和一个datetime进行加减
    print(d + t2)
    

    random 模块

    """
        random 随机数相关模块
            random 0-1 开闭
            randint 0 - 3 开开
            randrange 0 - 3 开闭
            choice [1,2,32,3,2,"哈哈"] 随机选⼀个
            sample([1,"a",["c","d"]],2) 随机选指定个数
            uniform(1,3) 闭闭 浮点
            shuffle(列表) 打乱顺序
    """
    import random
    # 0 - 1 随机浮点 不包含1
    print(random.random())
    # randint 0 - 3 开开
    print(random.randint(1,3))
    # randrange 0 - 3 开闭
    print(random.randrange(1,3))
    # choice [1,2,32,3,2,"哈哈"] 随机选⼀个
    print(random.choices((1,2,3)))
    # sample([1,"a",["c","d"]],2) 随机选指定个数
    print(random.sample([1,2,3],2))
    # shuffle(列表) 打乱顺序
    l = [1,2,3,4,5]
    print(random.shuffle(l))
    print(l)
    # uniform(1,3) 闭闭 浮点
    print(random.uniform(1,2))
    
    # 生产验证码 整形和字符(全大写)随机组成  可以指定长度
    def make_code(i):
        res = ""
        for j in range(i):
    #         随机0到9
            num = str(random.randint(0,9))
            c = chr(random.randint(65,90))
            s = random.choice([num,c])
            res += s
        return res
    print(make_code(4))
    
    # example
    import random
    print("掌声有请:第%s排 第%s位童鞋" % (random.randint(1,10),random.randint(1,8)))
    

    shutil 模块

    """
        shutil 模块
            用于简化文件操作  (文件的高级操作)
        常用方法
        copy
        move
        rm
        make_archive
    
    """
    import shutil
    import zipfile,tarfile
    #shutil.copyfileobj(open("a.txt","r",encoding="utf-8"),open("b.txt","w",encoding="utf-8"),length=1024)
    
    # 利用shutil来创建压缩文件  仅支持 tar 和zip格式 内部调用zipFIle tarFIle模块实现
    # shutil.make_archive("test","zip",root_dir="D:脱产三期视频Day17代码")
    
    # 解压zip
    # z = zipfile.ZipFile(r"D:脱产三期视频Day17	est.zip")
    # z.extractall()
    # z.close()
    
    # 解压tar
    # t = tarfile.open(r"D:脱产三期视频Day17	est.tar")
    # t.extractall()
    # t.close()
    
    
    # t = tarfile.open(r"D:脱产三期视频Day17mytar.tar","w")
    # t.add(r"D:脱产三期视频Day171_datetime_test.py")
    # t.close()
    
    

    sys 模块

    """
        sys模块
            系统相关
            一般用于设计脚本程序
        常用方法
        argv  获取cmd输入的参数
    """
    import sys
    print(sys.argv)
    print(sys.platform)
    # print(sys.exit(0))
    
    
    # 模拟进度条
    """
        当程序要进行耗时操作时例如  读写  网络传输
        需要给用户提示一个进度信息
        "[********        ]"
        "[*********       ]"
        "[************    ]"
        "[****************]"
    """
    # print("[*          ]")
    # print("[**         ]")
    
    print("[%-10s]" % ("*" * 1))
    print("[%-10s]" % ("*" * 2))
    print("[%-10s]" % ("*" * 3))
    print("[%-10s]" % ("*" * 4))
    
    # %的一些规范
    # print("%-%ds" % (30,"1"))
    #  # %-30s  % *   %-30s
    #  # %%-%ds   % 20
    # # %-20s  % "1212"
    # print("%%")
    # print(("%%-%ds" % 20) % "*" )
    
    # 比例 0 - 1     0.5
    def progress(percent,width=30):
        percent = percent if percent <= 1 else 1
        text = ("
    [%%-%ds]" % width) % ("*" * int((width * percent)))
        text = text + "%d%%"
        text = text % (percent * 100)
        print(  text  , end="")
    # progress(0.5)
    
    # 模拟下载
    # 文件大小
    import time
    file_size = 10240
    # 已经下载大小
    cur_size = 0
    while True:
        time.sleep(0.5)
        cur_size += 1021
        progress(cur_size / file_size)
        if cur_size >= file_size:
            print()
            print("finish")
            break
    

    OS 模块

    """
        OS模块
            os表示操作系统相关
            第一大块功能 就是围绕文件和目录的操作
    """
    import os,sys
    # 获取当前文件夹路径
    print(os.getcwd())
    # 获取当前文件路径
    print(__file__)
    print(os.stat("D:脱产三期视频Day17datetime_test.py"))
    print(sys.platform)
    print(os.name)
    # 获取当前文件目录
    print(os.system("dir"))
    # 获取系统环境变量
    print(os.environ)
    
    
    # path模块
    # 绝对路径
    print(os.path.abspath(r"bbb.txt"))
    # 连接
    print(os.path.join("C:","users","aaa.txt"))
    # 规范化
    print(os.path.normcase(r"/a/b/CSD"))
    print(os.path.normpath(r"acd.."))
    
    # 获取项目主目录
    print(os.path.dirname(os.path.dirname(__file__)))
    print(os.path.normpath(os.path.join(os.getcwd(), os.pardir)))
    
    

    pickle 模块

    """
    pickle模块:
        作用于序列化
        序列化就是将内存中的数据持久化到硬盘(二进制)
    回顾:使用文件读写也能完成把数据持久化存储,但是有局限性,当数据比较复杂时用起来就很麻烦
    例如:需要把一个字典存储到硬盘中 先转成字符串 写入 读取为字符串 转为原始的格式
    
    所以就有了pickle
    1.能将所有python中的数据序列化    int float str dic list tuple set bool
    2.反序列化  将之前序列化的数据 在恢复成python的数据格式
    
    pickle产生的数据,只能由python读取  (跨平台性差)
    今后你开发程序不可能就是单机程序,你需要和其他设备、其他平台交换数据
    我们需要找到一种通用的数据格式 让各个平台都能识别
    """
    users = {"name":"yyh","age":20,"hobbies":["打豆豆","飘"]}
    # f = open("a.txt","wt",encoding="utf-8")
    # f.write(str(users))
    # f.close()
    
    import pickle
    print(pickle.dumps(users))
    # 序列化
    f = open("p.txt","wb")
    f.write(pickle.dumps(users))
    f.close()
    
    # 反序列化
    f = open("p.txt","rb")
    print(pickle.loads(f.read()))
    print(type(pickle.loads(f.read())))
    f.close()
    
    # 序列化(另一种写法)
    pickle.dump(users,open("pp.txt","wb"))
    # 反序列化(另一种写法)
    print(pickle.load(open("pp.txt","rb")))
    

    json 模块

    """
    pickle产生的数据 只能由python读取  (跨平台性差)
    今后你开发程序不可能就是单机程序 你需要和其他设备 其他平台 交换数据
    我们需要找到一种通用的数据格式 让各个平台都能识别
    
    json模块:
        用于处理json格式数据的模块
        json 全称:JavaScrip Object Notation  js的对象表示法
         所以json能支持的数据类型就是js支持数据类型
    
    json格式标准
        能存储的有 str int float dic list bool
    案列:
    要求:数据的最开始和最末尾 必须是{} []
            {"name":"yyh"}
    json是一种通用的数据交换格式  目前主流的语言都能够轻松解析
    注意: 在使用json格式的时候 数据类型必须按照要求来写,并且,不支持python的元组、True/Flase、''、'''。
    
    常用方法
        序列化
            dump   处理文件
            dumps  处理字符串
        反序列化
            load  处理文件
            loads 处理字符串
    """
    # 将python格式的数据序列化为json格式  python中的任何类型都能被转化为json格式,只不过表现形式不同
    import json
    users = {'name':"音乐会","age":20,"hobbies":("music","movies")}
    print(json.dumps(users))
    print(type(json.dumps(users))) #str
    json.dump(users,open("users.json","wt",encoding="utf-8"))
    
    # json的反序列化
    jsonstr = json.load(open("users.json","r",encoding="utf-8"))
    print(jsonstr)
    

    总结

    """
        time 
            时间转换                    ****
        datetime
            获取时间                    ***
        os
            操作系统的文件路和目录 
            os.path                     *****
        sys
            解释器相关  用于设计脚本程序   ***
        pickle
            python本地序列化方式 比较局限  ** 
        json
            通用的数据交换格式 使用起来挺简单  *****
        shutil
            文件相关的高级操作                  ***
        random
            随机数相关   简单          ****
    """
    
  • 相关阅读:
    DOM 高级编程笔记
    什么是目标管理?什么叫smart原则?
    HTML文档中小meta的大作用
    《javascript权威指南》基础笔记 重要
    应聘时最漂亮的回答 转
    JS在IE和Firefox之间的区别
    apply与call的用法及区别
    谈谈Ajax跨域
    《高性能网站建设指南》、《高性能网站建设进阶指南》笔记
    HTTP协议状态码详解(HTTP Status Code)
  • 原文地址:https://www.cnblogs.com/chenwang-23/p/10946806.html
Copyright © 2011-2022 走看看