VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > Python基础教程 >
  • python基础教程之常用模块介绍

常用模块的介绍:

​ random
time,datetime
​ os,sys
​ hashlib,json,pickle,collections

random模块:

此模块提供了和随机数获取相关的方法:

  • random.random():获取[0.0,1.0)范围内的浮点数

  • random.randint(a,b):获取[a,b]范围内的一个整数

  • random.uniform(a,b):获取[a,b)范围内的浮点数

  • random.shuffle(x):把参数指定的数据中的元素打乱。参数必须是一个可变的数据类型。无返回值

  • random.sample(x,k):从x中随机抽取k个数据,组成一个列表返回。 有返回值

    import random
    # 获取[0.0,1.0)范围内的浮点数
      print(random.random())  #0.3255954890152818
    
    # 获取[a,b)范围内的浮点数
      print(random.uniform(3,5))#4.683774922271366
    
    # 获取[a,b]范围内的一个整数
      print(random.randint(3,10))#4
    
    # random.shuffle(x) 把参数指定的数据中的元素打乱。
      lst = list(range(10))
      random.shuffle(lst)
      print(lst)#[8, 3, 0, 9, 5, 1, 4, 6, 2, 7]
    
      t = (1,2,3)
      random.shuffle(t)  #报错,参数必须是一个可变的数据类型。
    
    # 通过sample变相实现打乱
      t = (1,2,3)
      lst = random.sample(t,len(t))
      print(lst)#[1, 3, 2]
    
      ##自: 利用random产生6位数字的验证码
          #1
          import random
          s = ''
          l = random.sample(range(10),6)
          for i in l:
              s += str(i)
          print(s) #如:937640
    
          #2:
          #获取[a,b]范围内的一个整数
          print(random.randint(100000,999999))# 如:337144
    

time模块:

  • time 模块(和时间相关):封装了获取时间戳和字符串形式的时间的一些方法。

  • 三大对象:时间戳, 结构化时间对象(9大字段), 时间字符串【重点】

    • time.time():获取时间戳

    • time.gmtime([seconds]):获取格式化时间对象:是九个字段组成的

    • time.localtime([seconds]):获取格式化时间对象:是九个字段组成的

    • time.mktime(t):时间对象 -> 时间戳

    • time.strftime(format[,t]):把时间对象格式化成字符串

    • time.strptime(str,format):把时间字符串转换成时间对象

    • time模块三大对象之间的转换关系

    • import time
      # 获取时间戳
      # 时间戳:从时间元年(1970 1 1 00:00:00)到现在经过的秒数。  python:秒数   java:毫秒数
          print(time.time())#1558317680.919616      #格林尼治时间
      
      # 获取格式化时间对象:是九个字段组成的。
           # 默认参数是当前系统时间的时间戳。默认使用time.time()的返回值。    tm_isdst夏令时
           print(time.gmtime())# GMT  time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=2, tm_min=1, tm_sec=20, tm_wday=0, tm_yday=140, tm_isdst=0)
                 模块名.方法名
      
          # 获取时间元年过一秒后,对应的时间对象
           print(time.gmtime(1))#time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=1, tm_wday=3, tm_yday=1, tm_isdst=0)
      
           print(time.localtime())#time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=10, tm_min=1, tm_sec=20, tm_wday=0, tm_yday=140, tm_isdst=0)
      
      # 时间对象 ---> 时间戳
           t1 = time.localtime()  #时间对象
           t2 = time.mktime(t1)   #获取对应的时间戳
           print(t2)#1558318103.0
           print(time.time())#1558318103.9826832
      
      
      # 格式化时间对象转换成字符串  strftime(format, p_tuple=None)
           s = time.strftime("%Y %m %d %H:%M:%S")  #注意大小写
           print(s,type(s))#2019 05 20 10:05:17 <class 'str'>
      
      # 把时间字符串转换成时间对象 strptime(string, format)
           time_obj = time.strptime('2019 05 20','%Y %m %d') #注意字符串中间加空格'2019 05 20'
           print(time_obj)#time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=140, tm_isdst=-1)
      
           time_obj = time.strptime('2019 05 20 12 30 55','%Y %m %d %H %M %S')
           print(time_obj)#time.struct_time(tm_year=2019, tm_mon=5, tm_mday=20, tm_hour=12, tm_min=30, tm_sec=55, tm_wday=0, tm_yday=140, tm_isdst=-1)
      
      #暂停当前程序,睡眠xxx秒  time.sleep(xxx)
           for i in range(5):
               print(time.strftime('%Y %m %d %H:%M:%S'))
               time.sleep(1)

datetime模块:

  • datetime模块:日期时间模块,封装了一些和日期、时间相关的类。 类包含若干属性和方法

    • date:需要年,月,日三个参数

    • time:需要时,分,秒三个参数

    • datetime:需要年,月,日,时,分,秒六个参数.

    • timedelta:需要一个时间段.可以是天,秒,微秒.

      • timedelta可以和以下三个类进行数学运算: datetime.time, datetime.datetime, datetime.timedelta
    • 获取以上类型的对象,主要作用是和时间段进行数学运算. 对时间日期进行数学计算

      import datetime
      
      #date类
           d = datetime.date(2019,5,20)
          #获取date对象的各个属性
           print(d)#2019-05-20
           print(d.year)#2019
           print(d.month)#5
           print(d.day)#20
      
      #time类:
           t = datetime.time(10,11,55)
           print(t)#10:11:55
          #获取time的各个属性
           print(t.hour)#10
           print(t.minute)#11
           print(t.second)#55
      
      #datetime类:
           dt = datetime.datetime(2019,5,20,10,11,46)
           print(dt)#2019-05-20 10:11:46
      
      #timedelta类:时间的变化量
           td = datetime.timedelta(days=1)
           print(td,type(td))#1 day, 0:00:00 <class 'datetime.timedelta'>
      
      ##参与数学运算:
      
      # 创建时间对象,只能和以下三类进行数学运算: date,datetime,timedelta
           【测试】:(date,datetime,timedelta分别于timedelta运算,datetime与date不能运算)
           td = datetime.timedelta(days=1)
           d = datetime.date(2010,10,10)
           res = d - td
           print(res)#2010-10-09
      
      
      #timedelta和时间段进行运算的结果类型: 和另一个操作数的类型保持一致
           td2 = datetime.date(2010,10,10)
           td = datetime.timedelta(days=1)
           res = d + td
           print(res,type(res))#2010-10-11 <class 'datetime.date'>
      
           d = datetime.datetime(2010,10,10,10,10,10)
           td = datetime.timedelta(days=1)
           res = d + td
           print(res,type(res))#2010-10-11 10:10:10 <class 'datetime.datetime'>
      
           d = datetime.timedelta(seconds=20)
           td = datetime.timedelta(days=1)
           res = d + td
           print(type(res),res)#<class 'datetime.timedelta'> 1 day, 0:00:20
      
      
      # 时间变化量的计算会产生进位。
           t = datetime.datetime(2010,12,31,23,59,58)
           td = datetime.timedelta(seconds=3)
           res = t + td
           print(res)#2011-01-01 00:00:01
      
           t = datetime.datetime(2010,10,10,10,10,00)
           td = datetime.timedelta(seconds=3)
           res = t - td
           print(res)#2010-10-10 10:09:57
      
      # 练习:计算某一年的二月份有多少天.
      # 普通算法:根据年份计算是否是闰年.是:29天,否:28
      
      # 用datetime模块.首先创建出指定年份的3月1号.然后让它往前走一天.
           year = int(input("请输入年份:"))
           d = datetime.date(year,3,1) # 创建指定年份的date对象
           td = datetime.timedelta(days=1) # 创建一天 的时间段
           res = d - td
           print(res.day)#根据输入的年份,显示 28 或 29
      

os模块:

  • os模块:和操作系统相关的操作被封装到这个模块中,主要是文件删除,目录删除,重命名等操作。(os模块是与操作系统交互的一个接口,它提供的功能多与工作目录,路径,文件等相关)

    目录指的是文件夹 。当前目录,工作目录,父级目录:指的都是一个,就是本文件所在的文件夹。

    import os
    #和文件操作相关:重命名,删除
    
    #重命名:文件,目录重命名,目标不能事先存在
       os.rename('a.txt','b.txt')
    
    #删除:
       os.remove('b.txt')
    
    #删除目录,必须是空目录
       os.rmdir('aa')
    
    #递归删除空文件夹
       os.removedirs('aa')
    
    #使用shutil模块可以删除带内容的(非空)目录(慎用)---自动化运维必会
         import shutil
         shutil.rmtree('aa')
    #和路径相关的属性(了解)
            os.curdir :当前路径
            os.sep :路径分隔符
            os.altsep :备用的分隔符
            os.extsep :扩展名分隔符
            os.pathsep :路径分隔符
            os.linesep :行分隔符,不要在写文件的时候,使用这个属性.
    #和路径相关的操作,被封装到另一个子模块中:os.path
      绝对路径:
          相对路径:
    
        #os.path.dirname(path) 返回一个路径中的父目录部分(不会判断路径是否存在)
             res = os.path.dirname(r'd:/aaa/bbb/ccc/a.txt')  #路径不存在,不会报错
             print(res)#d:/aaa/bbb/ccc
    
        #os.path.basename(path) 返回path指定的路径的最后一个内容.如果只是一个盘符,或者是以路径分隔符结尾的字符串,则返回空;否则返回的是 路径中的最后一部分内容.
             res = os.path.basename(r'd:/aaa/bbb/ccc.txt')  #路径不存在,不会报错
             print(res)#ccc.txt
             res = os.path.basename(r'd:/aaa/bbb/ccc')
             print(res)#ccc
    
        #os.path.split(path) 返回一个元组(只有两个元素),第二个元素表示的是最后一部分的内容,第一个元素表示的是剩余的内容.
          如果只是一个盘符或者是以路径分隔符结尾的字符串,则第二个元素为空。否则第二个元素就是最后一部分的内容。如果path中不包含路径分隔符,则第一个元素为空.
             res = os.path.split(r'd:/aa/bb/cc/a.txt')  #路径不存在,不会报错
             print(res)#('d:/aa/bb/cc', 'a.txt')
    
        #os.path.join(path,*paths)拼接路径
          如果路径中有绝对路径,则在这个路径之前的路径都会被丢弃,而从这个路径开始往后拼接.
          Windows中盘符一定要带\,否则不认为是一个盘符.
    
             path = os.path.join('aaa','bbb','ccc','a.txt')
             print(path)#aaa\bbb\ccc\a.txt
             path = os.path.join('d:\\''aaa','bbb','ccc','a.txt')
             print(path)#d:\aaa\bbb\ccc\a.txt
    
    
        #os.path.abspath(path) 返回一个路径的绝对路径
    
             如果参数路径以/开始,则把当前盘符和参数路径连接起来组成字符串返回
             如果参数路径是相对的路径,就把当前路径和参数路径的组合字符串当成结果返回
             如果参数路径已经是绝对路径,就直接把参数返回.  
    
        注意: 此方法只是简单的将一个拼接好的字符串返回,并不会去检查这个字符串表示的文件是否存在.
    
             #如果是/开头的路径,默认是在当前盘符下
                 res = os.path.abspath(r'/a/b/c')
                 print(res)#D:\a\b\c
             #参数路径是相对的路径
                 res = os.path.abspath(r'a/b/c')
                 print(res)#D:\python22\day16\a\b\c
    
                 res = os.path.abspath('aa')
                 print(res)#D:\python22\day16\aa
             #参数路径已经是绝对路径  
                res = os.path.abspath(r'd:\c\aa\bb')
                print(res)#d:\c\aa\bb
    
        #os.path.getsize(path) :获取文件的字节数.如果是文件夹,返回0或者是一个不准确的值
                print(os.path.getsize('aa')) # 0
                print(os.path.getsize('.')) # 4096
                print(os.path.getsize('aa/test.txt')) # 6
    
         #判断功能:
         #判断是否是绝对路径:
             print(os.path.isabs('d:/a.txt'))#True  路径不存在,不会报错
             print(os.path.isabs('a.txt'))#False
    
         #判断是否是目录:
             print(os.path.isdir('d:/aaa.txt'))#False  aaa.txt文件夹不存在  或者 aaa.txt是文件  从文件名不能判断是文件还是目录
             print(os.path.isdir('d:/aaa.txt'))#True  aaa.txt文件夹存在的情况
    
         #判断路径是否真正存在:
             print(os.path.exists('d:/a.txt'))#False    a.txt不存在
             print(os.path.exists('d:/s22/aaa.txt'))#True  aaa.txt存在的情况
             print(os.path.exists('d:/s22'))#True
    
         #判断是否是文件:
             print(os.path.isfile('d:/aaaa.txt'))#False  文件不存在的情况
             print(os.path.isfile('d:/s22'))#False  是目录的情况
             print(os.path.isfile('d:/s22/aaa.txt'))#True
    
    
         #【补充】:三颗星是需要记住的。
          # 工作目录:在哪个文件下执行的这个py文件,哪一个目录就是你的工作目录
          当前执行这个python文件的工作目录相关的工作路径
          os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径  ** 
          os.chdir("dirname")  改变当前脚本工作目录;相当于shell下cd  **
          os.curdir  返回当前目录: ('.')  **
          os.pardir  获取当前目录的父目录字符串名:('..') **
    
          # 和文件夹相关 
          os.makedirs('dirname1/dirname2')    可生成多层递归目录  ***
          os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 ***
          os.mkdir('dirname')    生成单级目录;相当于shell中mkdir dirname ***
          os.rmdir('dirname')    删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname ***
          os.listdir('dirname')    列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 **
    
          # 和文件相关
          os.remove()  删除一个文件  ***
          os.rename("oldname","newname")  重命名文件/目录  ***
          os.stat('path/filename')  获取文件/目录信息 **
    
          # 和操作系统差异相关
           os.sep    输出操作系统特定的路径分隔符,win下为"\\",Linux下为"/" *
           os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" *
           os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为: *
           os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix' *
    
          # 和执行系统命令相关
           os.system("bash command")  运行shell命令,直接显示  **
           os.popen("bash command).read()  运行shell命令,获取执行结果  **
           os.environ  获取系统环境变量  **
             #示例:       
              import os
              os.system('dir')
              ret = os.popen('dir')
              print(ret.read())
    
          #path系列,和路径相关
          os.path.abspath(path) 返回path规范化的绝对路径  ***
          os.path.split(path) 将path分割成目录和文件名二元组返回 ***
          os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素  **
          os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值,即os.path.split(path)的第二个元素。 **
          os.path.exists(path)  如果path存在,返回True;如果path不存在,返回False  ***
          os.path.isabs(path)  如果path是绝对路径,返回True  **
          os.path.isfile(path)  如果path是一个存在的文件,返回True。否则返回False  ***
          os.path.isdir(path)  如果path是一个存在的目录,则返回True。否则返回False  ***
          os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 ***
          os.path.getatime(path)  返回path所指向的文件或者目录的最后访问时间  **
          os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间  **
          os.path.getsize(path) 返回path的大小 ***
    

sys模块:

  • sys模块:和python解释器相关的操作。sys模块是与python解释器交互的一个接口


       import sys       #sys默认使用os,但是要使用os,还要手动导入。
      #获取命令行方式运行的脚本后面的参数:sys.argv[x]
       sys.argv 在运行python脚本的时候写在python命令后面的是啥,打印出来的就是啥
          应用:
          在运维里常用的操作方式:所有操作不需要进入程序后再根据提示输入,而是通过命令行的方式完成相关操作。直接在执行文件的时候,给它指令,让它根据指令直接完成一些操作。通过一条命令完成相关操作,使用方便。
          #示例1: 
           print('脚本名:',sys.argv[0])   #脚本名:D:\python22\day16\tt16.py
           print('第一个参数:',sys.argv[1])  #第一个参数: hello
           print('第二个参数:',sys.argv[2])  #第二个参数: world
           print(type(sys.argv[1]))  #<class 'str'>
           print(type(sys.argv[2]))  #<class 'str'>
    
          #示例2:
           import sys
           if sys.argv[1] == 'alex' and sys.argv[2] == 'sb':
               print('登录成功')
    
      #sys.path :系统寻找模块的路径.
      路径的第一项path[0]始终是调用解释器的脚本所在的路径(相对路径).程序中可以随时对这个路径进行修改.以达到动态添加模块路径的目的.
      print(sys.path)   
    
      #sys.modules :返回系统已经加载的模块,以字典形式返回.查看导入了哪些模块
      print(sys.modules)
    #补充:
      sys.argv           命令行参数List,第一个元素是程序本身路径
      sys.exit(n)        退出程序,正常退出时exit(0),错误退出sys.exit(1)
      sys.version        获取Python解释程序的版本信息
      sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值  ***
      sys.platform       返回操作系统平台名称
    
    

hashlib模块:

  • hashlib模块:封装一些用于加密的类.hashlib模块中提供的类采用的是单向加密算法,也称'哈希算法','摘要算法'

    • 加密的目的:用于判断和验证,而并非解密。给一个数据加密,然后用另一个数据加密的结果和第一次加密的结果对比。如果结果相同,说明原文相同.如果不相同,说明原文不同.
    • 特点:
      • 把一个大的数据,切分成不同块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据加密的结果是一致的.
      • 单向加密,不可逆.从加密后的结果反推原始数据几乎是不可能的.
      • 原始数据的一点小的变化,将导致结果的非常大的差异,'雪崩'效应.
  • 给一个数据加密的三大步骤:

    例如:md5加密算法:

    1.获取一个加密算法对象
    2.使用加密对象的update,进行加密,update方法可以调用多次,意味着在前一次的update结果之上,再次进行加密.。参数必须是字节类型
    3.通常通过 hexdigest() 获取加密结果 或 digest()方法.

    ​ 密文:加密的结果

    ​ 原文:

    import hashlib
    # 获取一个加密对象
       m = hashlib.md5()
    
    # 使用加密对象的update方法进行加密  ---> 加密结果可以累加
         m.update('abc中文'.encode('utf-8'))  #对字节进行加密
         m.update('def'.encode('utf-8'))
         m.update(b'def')  #在字符串前加b,包含中文时,不能直接在前面加b
    
    # 通过hexdigest获取加密结果:字符串形式
         res = m.hexdigest()
         print(res)#2f1b6e294e72d25ae196fe4ac2d27de6
    
     #通过digest获取加密结果 :字节形式      
         res1 = m.digest()   ###通过digest获取加密结果,得到的是字节串
         print(res1)#b'/\x1bn)Nr\xd2Z\xe1\x96\xfeJ\xc2\xd2}\xe6'
    
    
    # 不同加密算法(不同的加密对象),实际上就是加密结果的长度不同,长度越长,越耗时.常用的是md5
      加密对象除了md5之外,还有如下几种:
        #'sha1', 'sha224', 'sha256', 'sha384', 'sha3_224', 'sha3_256', 'sha3_384', 'sha3_512','sha512', 'shake_128', 'shake_256'
    
        print(len(hashlib.md5().hexdigest()))#32
         print(len(hashlib.sha224().hexdigest()))#56
         print(len(hashlib.sha256().hexdigest()))#64
    
    # 在创建加密对象时,可以指定参数,称为salt(盐),目的就是为了让加密的结果更加复杂.。
         #1:
         m = hashlib.md5(b'abc')
         print(m.hexdigest())#900150983cd24fb0d6963f7d28e17f72
         #2:同上面是等价的
         m = hashlib.md5()
         m.update(b'abc')
         print(m.hexdigest())#900150983cd24fb0d6963f7d28e17f72
    
         m = hashlib.md5()
         m.update(b'abc')
         m.update(b'def')
         print(m.hexdigest())#e80b5017098950fc58aad83c8c14978e
    
    
    #注册登录:
    
    
         #注册登录(简版):
            def get_md5(username,passwd):   #加密
                m = hashlib.md5(username[::-1].encode('utf-8'))#加盐,将用户名反转,再转化为二进制字节
                #m.update(username.encode('utf-8'))
                m.update(passwd.encode('utf-8'))
                return m.hexdigest()
    
            def register(username,passwd):  #注册
                res = get_md5(username,passwd)
                with open('login',mode='at',encoding='utf-8') as f:
                    f.write(res)
                    f.write('\n')
    
            def login(username,passwd):   #登录
                res = get_md5(username, passwd)# 获取当前登录信息的加密结果 
                with open('login',mode='rt',encoding='utf-8') as f: # 读文件,和其中的数据进行对比
                    for line in f:
                        if res == line.strip():
                            return True
                    else:
                        return False
    
            while True:
                op = int(input("1.注册 2.登录 3.退出"))
                if op == 3 :
                    break
                elif op == 1:
                    username = input("输入用户名:")
                    passwd = input("输入密码:")
                    register(username,passwd)
                elif op == 2:
                    username = input("输入用户名:")
                    passwd = input("输入密码:")
                    res = login(username,passwd)
                    if res:
                        print('登录成功')
                    else:
                        print('登录失败')
    
    


结构化数据:背后有很多方法、属性支撑着它,如字符串

磁盘上的数据:线性数据(流式数据):数据之间没有引用关系

json模块:

  • json模块:

    • JavaScript Object Notation:java脚本对象标记语言.已经成为一种简单的数据交换格式.
    • 序列化:将其他数据格式转换成json字符串的过程.
    • 反序列化:将json字符串转换其他数据类型的过程.
    • 涉及到的方法:
      • json.dumps(obj):将obj转换成json字符串返回到内存中. 返回到内存中
      • json.dump(obj,fp):将obj转换成json字符串并保存在fp指向的文件中. 序列化到文件中
      • json.loads(s):将内存中的json字符串转换成对应的数据类型对象
      • json.load(f):从文件中读取json字符串,并转换回原来的数据类型. 从文件中反序列化,在文件中有一个json字符串,进行反序列化
  • 注意:

    • json并不能序列化所有的数据类型:例如:set集合 。

    • 元组数据类型经过json序列化后,变成列表数据类型。

    • json文件通常是一次性写入,一次性读取,但是可以利用文件本身的方式实现:一行存储一个序列化json字符串,在反序列化时,按行反序列化即可。

    • 通常json文件用来保存一些配置信息,这样的配置信息不会太大.通过一次写,一次读,完全可以满足数据交换的需求.

    • import json
      ##序列化:
      
       # json.dumps:将数据转换成字符串,用于存储或网络传输。
      
           s = json.dumps([1,2,3]) # 把指定的对象转换成json格式的字符串
           print(type(s))#<class 'str'>
           print(s)#[1, 2, 3]
      
          s = json.dumps((1, 2, 3))  # 元组序列化后,变成列表形式的字符串
          print(s,type(s))  #[1, 2, 3] <class 'str'>
          l = json.loads(s)
          print(l,type(l))#[1, 2, 3] <class 'list'>
      
           res = json.dumps(10)
           print(res,type(res))#10 <class 'str'>
      
           res = json.dumps({'name':'alex','age':88})
           print(res,type(res))#{"name": "alex", "age": 88} <class 'str'>
      
           res = json.dumps(set('abc'))
           print(res)#TypeError: Object of type 'set' is not JSON serializable
      
      
       # json.dump
          #将json结果写到文件中  
           with open('a.txt',encoding='utf-8',mode='a') as f:
               json.dump([1,2,3],f)
      
      
      #反序列化:
          #json.loads
               res = json.dumps([1,2,3])
               lst = json.loads(res)   ## 反序列化
               print(lst,type(lst))#[1, 2, 3] <class 'list'>
      
              # 元组会变成列表
               res = json.dumps((1,2,3))
               lst = json.loads(res)           # 反序列化
               print(lst,type(lst))#[1, 2, 3] <class 'list'>
      
          #json.load
          #从文件中反序列化:
               with open('a.txt',encoding='utf-8') as f:
                   res = json.load(f)
               print(res,type(res))#[1, 2, 3] <class 'list'>
      
      
      
      # json文件通常是一次性写,一次性读.使用另一种方式,可以实现多次写,多次读.
          # 把需要序列化的对象.通过多次序列化的方式, 用文件的write方法,把多次序列化后的json字符串写到文件中
               with open('json.txt',encoding='utf-8',mode='a') as f:
                   f.write(json.dumps([1,2,3]) + '\n')   #此时只能用dumps,不能用dump
                   f.write(json.dumps([4,5,6]) + '\n')
      
          #  把分次序列化的json字符串,反序列化回来
               with open('json.txt',encoding='utf-8',mode='r') as f:
                   res1 = json.loads(f.readline().strip())
                   print(res1)
                   res2 = json.loads(f.readline().strip())
                   print(res2)
                   # [1, 2, 3]
                   # [4, 5, 6]
      
          #使用循环改进:
               with open('json.txt',encoding='utf-8',mode='r') as f:
                   for line in f:
                       res = json.loads(line.strip())  #此时只能用loads,不能用load
                       print(res)
              #  [1, 2, 3]
              #  [4, 5, 6]
      
      

pickle模块:

  • 序列化过程:将Python中所有的数据类型.转换成字节串。

  • 反序列化过程:将字节串转换成python中数据类型。

  • pickle常用场景:和json一样,一次性写入,一次性读取。 (可以多次写,多次读)

  • pickle: python专用的序列化模块,和json的方法一致。

  • json,pickle的比较:

    • json:

      • 1.不是所有的数据类型都可以序列化.结果是字符串.
      • 2.不能多次对同一个文件序列化.
      • 3.json数据可以跨语言传输数据
      • 4.序列化的结果是字符串
    • pickle:

      • 1.所有python类型都能序列化,结果是字节串.
      • 2.可以多次对同一个文件序列化
      • 3.不能跨语言,只在python中使用
      import pickle
      
      #python所有的数据类型都可以进行序列化
      
      # 列表序列化
           bys = pickle.dumps([1,2,3])
           print(bys,type(bys))#b'\x80\x03]q\x00(K\x01K\x02K\x03e.' <class 'bytes'>
      
      # 保存了元组的数据类型
           bys = pickle.dumps((1,2,3))#序列化
           print(bys,type(bys))#b'\x80\x03K\x01K\x02K\x03\x87q\x00.' <class 'bytes'>
           res = pickle.loads(bys)  #反序列化
           print(res,type(res))#(1, 2, 3) <class 'tuple'>
      
      # 集合序列化,反序列化
           bys = pickle.dumps(set('abc'))
           print(bys,type(bys))#b'\x80\x03cbuiltins\nset\nq\x00]q\x01(X\x01\x00\x00\x00cq\x02X\x01\x00\x00\x00bq\x03X\x01\x00\x00\x00aq\x04e\x85q\x05Rq\x06.' <class 'bytes'>
           res = pickle.loads(bys)
           print(res,type(res))#{'c', 'b', 'a'} <class 'set'>
      
      
      # 把pickle序列化内容写入到文件:
           with open('cc.txt',mode='wb') as f:  #转化成字节
               pickle.dump([1,2,3],f)
      
      # 从文件中反序列化pickle数据
           with open('cc.txt',mode='rb') as f:   #字节
               res = pickle.load(f)
               print(res,type(res))#[1, 2, 3] <class 'list'>
      
      
      # 多次pickle数据到同一个文件中
           with open('cc.txt',mode='ab') as f:
               pickle.dump([1, 2, 3], f)
               pickle.dump([1, 2, 3], f)
               pickle.dump([1, 2, 3], f)
               pickle.dump([1, 2, 3], f)
      
      # 从文件中多次反序列化pickle数据:
           with open('cc.txt',mode='rb') as f:
               for i in range(4):
                   res = pickle.load(f)
                   print(res)
          # [1, 2, 3]
          # [1, 2, 3]
          # [1, 2, 3]
          # [1, 2, 3]
      

collections模块:

  • collections模块:此模块定义了一些内置容器类数据类型之外,可用的集合类数据类型.

    • namedtuple():命名元组。元组的工厂函数

    • deque()双端队列,可以快速的从另外一侧追加和推出对象

    • OrderedDict():有序字典

    • defaultdict():默认值字典.

    • Counter():计数器,主要用来计数 #首字母必须大写

      import collections
      
      # namedtuple()
          所谓的工厂函数指的是:接收类名和一些创建此类对象所需要的一些参数,返回指定类的一个对象.命名元组的特点是给元素绑定了一个有意义的名字.在使用元素时可以使用元素的名字而不必使用索引
          第一个参数指定的是返回的子类的类名。第二个参数指定的是子类元组可以拥有的元素名.以字符串组成的列表表示,或者是以空格,逗号分隔的单个字符串都可以。
      
           #用来表示矩形的长和款:
              Rectangle = collections.namedtuple('Rectangle_class',['length','width'])         #'Rectangle_class'为说明信息,不能有空格
              r = Rectangle(10,6)
      
              # 通过属性访问元组的元素
                print(r.length)#10
                print(r.width)#6
              # 通过索引的方式访问元素
                print(r[0])#10
                print(r[1])#6
      
      
          #用来表示一个点的二维坐标:
               from collections import namedtuple
               Point = namedtuple('Point', ['x', 'y'])
               p = Point(1, 2)
               print(p.x)#1
               print(p.y)#2
      
          #类似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:
              namedtuple('名称', [属性list]):
              Circle = namedtuple('Circle', ['x', 'y', 'r'])
      
      #deque()双端队列,可以快速的从另外一侧追加和推出对象
          使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈。deque除了实现list的append()和pop()外,还支持appendleft()和popleft(),这样就可以非常高效地往头部添加或删除元素。
              from collections import deque
              q = deque(['a', 'b', 'c'])
              q.append('x')
              q.appendleft('y')
              print(q)#deque(['y', 'a', 'b', 'c', 'x'])
      
      #OrderedDict()
          使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。如果要保持Key的顺序,可以用OrderedDict。注意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序。
              from collections import OrderedDict
              d = dict([('a', 1), ('b', 2), ('c', 3)])
              print(d )# dict的Key是无序的{'a': 1, 'c': 3, 'b': 2}
              od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
              print(od) # OrderedDict的Key是有序的 OrderedDict([('a', 1), ('b', 2), ('c', 3)])
      
      #defaultdict:默认字典
       # 创建字典的方式:
           d = {'name':'alex','age':84}
           print(d)#{'name': 'alex', 'age': 84}
           d = dict([('name','alex'),('age',84)])
           print(d)#{'name': 'alex', 'age': 84}
           d = { k:v for k,v in [('name','alex'),('age',84)]}
           print(d)#{'name': 'alex', 'age': 84}
      
      # defaultdict()
          第一个参数指定的是一个函数名,用来表示当字典对象中出现了不存在的键时,对应的值初始值是如何计算.正因为这个函数是获取值的,所以,对这个函数规定:不能有参数.默认情况下,第一个参数是None,意味着不存在的键对应的值为None.
              一旦使用defaultdict 时,指定了不存在的键,则会引发两件事情:1.调用第一个参数指定的函数得到默认值 2.把返回值赋值给这个新键.
           d = collections.defaultdict(int,name='alex',age=84)
           print(d['name'])#alex
           print(d['age'])#84
           print(d['addr'])#0     # {'addr':0} 也会被添加到字典
           print(d)#defaultdict(<class 'int'>, {'name': 'alex', 'age': 84, 'addr': 0})
      
           d = collections.defaultdict(bool,name='alex',age=84)
           print(d['name'])#alex
           print(d['age'])#84
           print(d['addr'])  #False   # {'addr':False} 也会被添加
           print(d)# defaultdict(<class 'bool'>, {'name': 'alex', 'age': 84, 'addr': False})
      
      
          # 可自定义:自定义函数充当其第一个参数,要求自定义函数不能有参数
               def f():
                   return 'hello'
      
               d = collections.defaultdict(f,name='Andy',age=20)  #第一个参数:函数名    第二,三个是传参:关键字不能加引号
               print(d['addr'])#hello
               print(d)# defaultdict(<function f at 0x000002A685A41E18>, {'name': 'Andy', 'age': 20, 'addr': 'hello'})
      
      
      # Counter :生成统计信息,用于统计可哈希对象的数量。
              是dict的子类.一种特殊的字典.它的键是可哈希对象,值是这个对象的个数统计信息。Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。
      
           c = collections.Counter('asdfgkoiunbbsgfawpag')  #括号内为可哈希对象
           print(c)#Counter({'a': 3, 'g': 3, 's': 2, 'f': 2, 'b': 2, 'd': 1, 'k': 1, 'o': 1, 'i': 1, 'u': 1, 'n': 1, 'w': 1, 'p': 1})
           #显示数量最多的前几名.
           print(c.most_common(3))#[('a', 3), ('g', 3), ('s', 2)]
      
      
          c = Counter('12435634567')
          print(c)
          print(c.most_common(3)) 
          #Counter({'4': 2, '3': 2, '5': 2, '6': 2, '1': 1, '2': 1, '7': 1})
          #[('4', 2), ('3', 2), ('5', 2)]
      
    •  


相关教程