Python 常用模块简析

Python 常用模块简析

  1. reandom:随机数获取

    • random.random():获取[0.0,1.0)之间内的随机浮点数。

      print(random.random())		# 不包含1,取不到1.0
      
    • random.randint(a,b):获取指定[a,b]区间内的随机整数。

      print(random.randint(3, 5))		# 随机获取3到5之间的整数,可以取到3和5
      
    • random.uniform(a,b):获取[a,b)范围内的随机浮点数。

      print(random.uniform(3, 5))		# 随机获取3到5(不包含5)之间的随机浮点数
      
    • random.shuffle(x):混洗,把参数所包含的元素进行打乱,x必须为可变数据类型。

      list1 = list(range(10))
      random.shuffle(list1)
      print(list1)
      
    • random.sample(x,k):随机取样,从x中随机抽取k个数据,组成一个列表返回。

    • random.choice(x):从x(元组或列表)中随机抽取一个元素

      # tuple元组是不可变数据类型,可以通过random.sample()函数实现打乱顺序
      tup = tuple(range(10))
      print(random.choice(tup))		# 从tup中随机抽取一个元素返回
      lst = random.sample(tup, len(tup))  # 从tup中提取全部元素进行随机排序,返回一个列表
      print(lst)
      # 此功能一般用于在某个序列内随机取样。
      
    • random.choices(population,weights=None,*,cum_weights=None,k=1):从指定序列中随机抽取k次数据,返回一个列表,可以设置权重

      • population:集群。
      • weights:相对权重。
      • cum_weights:累加权重。
      • k:选取次数。

      注意:每次选取都不会影响原序列,每一次选取都是基于原序列

      import random
      a = [1,2,3,4,5]
      print(random.choices(a,k=6))
      解析:重复6次从列表a中的各个成员中选取一个数输出,各个成员出现概率基本持平。
      结果:[5, 4, 5, 4, 1, 3](随机生成的)
      print(random.choices(a,weights=[0,0,1,0,0],k=6))
      解析:重复6次从列表a中提取3,最终得到[3, 3, 3, 3, 3, 3]
      结果:[3, 3, 3, 3, 3, 3](固定结果)
      print(random.choices(a,weights=[1,1,1,1,1],k=6))
      解析:重复6次从列表a中的各个成员中选取一个数输出,各个成员出现概率基本持平。
      结果:[5, 4, 3, 5, 4, 3](随机生成的)
      print(random.choices(a,cum_weights=[1,1,1,1,1],k=6))
      结果:[1, 1, 1, 1, 1, 1](固定结果)
      
      参数weights设置相对权重,它的值是一个列表,设置之后,每一个成员被抽取到的概率就被确定了。
      比如weights=[1,2,3,4,5],那么第一个成员的概率就是P=1/(1+2+3+4+5)=1/15。
      
      cum_weights设置累加权重,Python会自动把相对权重转换为累加权重,即如果你直接给出累加权重,那么就不需要给出相对权重,且Python省略了一步执行。
      比如weights=[1,2,3,4],那么cum_weights=[1,3,6,10]
      这也就不难理解为什么cum_weights=[1,1,1,1,1]输出全是第一个成员1了。
      
  2. time:和时间相关

    这个模块封装了获取时间戳和字符串形式时间的一些方法。

    • 时间戳:从时间元年(1970年1月1日0点0分0秒)到现在经过的秒数print(time.time())

    • 获取结构化时间对象:time.gmtime() 默认参数是当前系统时间的时间戳
      print(time.gmtime())	# 当前系统时间的格林尼治时间戳
      >>>time.struct_time(tm_year=2020, tm_mon=12, tm_mday=4, tm_hour=8, tm_min=35, tm_sec=17, tm_wday=4, tm_yday=339, tm_isdst=0)
      print(time.gmtime(1))	# 获取时间元年后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)
      
    • 获取结构化本地时间对象:time.localtime()

      用法与gmtime()方法一样,但获取得到的是当前时区的时间戳。

    • 格式化时间对象和字符串之间的转换:
      把格式化时间对象转换成字符串:time.strftime(字符串格式,时间戳)
      s = time.strftime("%Y-%m-%d  %H:%M:%S", time.localtime())  # 不能有中文字符,否则报错
      print(s)
      >>>2020-12-04  17:11:23
      
    • 把时间字符串转换成格式化时间对象:time.strptime(字符串,时间格式)
      time_obj=time.strptime('2020 09 10','%Y %m %d')
      print( time_obj)
      >>>time.struct_time(tm_year=2020, tm_mon=9, tm_mday=10, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=254, tm_isdst=-1)
      
      时间日期格式化符号
      %y 两位数的年份表示(00-99) %Y 四位数的年份表示(000-9999)
      %m 月份(01-12) %d 月内中的一天(0-31)
      %H 24小时制小时数(0-23) %I 12小时制小时数(01-12)
      %M 分钟数(00=59) %S 秒(00-59)
      %a 本地简化星期名称 %A 本地完整星期名称
      %b 本地简化的月份名称 %B 本地完整的月份名称
      %c 本地相应的日期表示和时间表示 %j 年内的一天(001-366)
      %p 本地A.M.或P.M.的等价符 %w 星期(0-6),星期天为星期的开始
      %U 一年中的星期数(00-53)星期天为星期的开始 %W 一年中的星期数(00-53)星期一为星期的开始
      %Z 当前时区的名称 %% %号本身
    • 格式化时间对象(time.struct_time)==>时间戳:time.mktime(时间对象)
      print(time.mktime(time.localtime()))
      >>>1607081631.0
      
    • 暂停当前线程,睡眠x秒
      time.sleep(秒数)
      
  3. datetime:日期和时间模块

    封装了一些和日期、时间相关的类,datetime中的类主要是用于数学计算的。

    • date类:包含有年月日属性
      import datetime
      d=datetime.date(2020,12,5)
      print(f'{d.year}年{d.month}月{d.day}日')
      >>>2020年12月5日
      
    • time类:包含时分秒属性
      t = datetime.time(18, 35, 59)
      print(f'{t.hour}点{t.minute}分{t.second}秒')
      >>>18点35分59秒
      
    • datetime类:包含年月日时分秒属性
      dt=datetime.datetime.now()
      print(dt)
      print(f'现在是{dt.year}年{dt.month}月{dt.day}日,{dt.hour}时{dt.minute}分{dt.second}秒{dt.microsecond}微秒')
      >>>2020-12-05 16:35:41.396585
      >>>现在是2020年12月5日,16时35分41秒396585微秒
      
    • timedelta类:时间的变化量,运算对象可以有date、datetime、timedelta
      t = datetime.datetime(2020, 10, 31, 14, 5, 59)		# 设定时间为2020.10.31,14:05:59
      td = datetime.timedelta(days=1, seconds=1)			# 时间变化量为1天零秒
      print(t + td)				# 进行运算之后会将变化量体现出来
      >>>2020-11-01 14:06:00
      

      例:计算某一年的2月份有几天。

      ​ 普通算法:根据年份计算是否闰年,再得出2月份天数;

      ​ 使用timedelta模块,首先创建出指定年份的3月1日,然后让它倒退1天,即可以得出2月最后一天日期。

      year = int(input('请输入年份:'))
      d = datetime.date(year, 3, 1)
      td = datetime.timedelta(days=1)
      print((d-td).day)
      

      和时间段timedelta类进行运算之后,结果的类型如何判断:

      运算结果类型 ==> 运算时第一个操作数的类型一致。

  4. os、sys

    • os模块:和操作系统相关的操作被封装到这个模块中。

      1. 和文件操作相关:重命名,删除

        os.rename('a.txt','b.txt),对a.txt文件进行重命名

        os.remove('a.txt'),对a.txt文件进行删除

      2. 对目录进行操作:删除空目录

        os.removedirs('aa'):删除aa目录

      3. 获取当前工作目录路径

        os.getcwd():返回一个当前目录字符串

      4. 获取当前(指定)目录下所有文件和子目录列表

        os.listdir(路径):默认返回当前工作目录下所有文件和子目录名的列表,也可以指定路径

      5. 附带内容:删除有内容的目录,删除目录树,需要shutil模块支持
        import shutil
        shutil.rmtree('aa')		# 直接删除整个aa目录
        
      6. os.path模块:和路径相关的操作方法
        • os.path.dirname:获取指定文件或路径的父目录(指定路径不需要真实存在)

          path = os.path.dirname(r'c:\windows\system32\host')
          print(path)
          >>>c:\windows\system32
          
        • os.path.basename:获取指定路径文件名(指定路径不需要真实存在)

          filename = os.path.basename(r'c:\windows\system32\fonts\xxx.font')
          print(filename)
          >>>xxx.font
          
        • os.path.split(r'd:/aaa/bbb/ccc/a.txt'):将指定路径中的路径和文件名切分开,返回一个元组。

        • os.path.join('d:\\','aaa','bbb','ccc','a.txt'):将指定字符串拼接成一个完整的路径地址。

        • os.path.abspath('.aaa/bbb/ccc/a.txt'):反回当前工作目录下指定路径的绝对路径

        • os.path.isabs('a.txt'):判断是否绝对路径

        • os.path.isdir('aaa.jpg'):判断对象是否为目录,文件不存在为False

        • os.path.isfile('d:\\backup.cdr'):判断对象是否为文件,文件不存在为False

        • os.path.exists('c:/autoexec.bat'):判断文件是存存在。

    • sys模块:和python解释器相关的操作

      1. 获取命令行方式运行的脚本后面的参数,sys.argv[0]为该脚本绝对路径和文件名。
        import sys
        arg1=int(sys.argv[1])
        arg2=int(sys.argv[2])
        print(arg1+arg2)
        ---------终端脚本方式运行以上程序-----------
        G:\python>python os_sys_demo.py 2 8
        10
        
      2. sys.path:返回当前系统中解释器注册的路径 ,可以通过PYTHONPATH来进行初始化。

        由于是在程序执行的时候进行初始化的,所以,路径的第一项path[0]始终是调用解释器脚本所在的路径。如果是动态调用的脚本,或者是从标准输入读取到脚本命令,则path[0]是一个空字符串。程序中可以随时对这个路径进行修改,以达到动态添加模块路径的目的。

      3. sys.modules:返回系统已经加载的模块,以字典形式返回。

        对这个字典中的值进行修改并没有什么具体意义,反而有时会引发异常。

        常用来作为是否重新加载一个模块的判断依据。

  5. json模块:将数据转换成字符串,用于存储或网络传输。

    JavaScript Object Notation:java脚本对象标记(描述)语言,它将所有的内容都转换成字符串,目前已经成为了简单的数据交换格式。

    Python中除了“集合”类型无法转换之外,其他都支持。

    • serialization:序列化,将内存中的数据,转换成字节串用以保存在文件或者通过网络传输,这称为序列化过程。
      1. json.dumps(obj):将数据对象进行序列化,元组可以被json序列化,但是经过json序列化之后会变成列表。

        list1 = json.dumps([1, 2, 3])
        print(list1, type(list1))
        tuple1 = json.dumps((44, 33, 22))	# 元组被序列化之后会变成列表
        print(tuple1, type(tuple1))
        dict1 = json.dumps({'name': 'amwkvi', 'age': 18})
        print(dict1, type(dict1))
        >>>[1, 2, 3] <class 'str'>
        [44, 33, 22] <class 'str'>
        {"name": "amwkvi", "age": 18} <class 'str'>
        
      2. json.dump(obj,文件句柄):json模块直接操作文件句柄,该方法操作对象为文件,将数据对象序列化之后写进文件。

        with open('a.txt', mode='at', encoding='utf-8') as f:
            json.dump(['abc', 112233, True, 3.23], f)
            json.dump(list1, f)
        -----------运行结果:创建一个a.txt文件,内容为以下---------------
        ["abc", 112233, true, 3.23]"[1, 2, 3]"
        
    • deserialization:反序列化,将文件中或网络中接收到的数据转换成内存中原来的数据类型,这称为反序列化过程。
      1. json.loads(obj):将数据对象进行反序列化,将json字符串反序列化为原数据类型。

        list2=json.loads(list1)
        print(list2,type(list2))
        tuple2=tuple(json.loads(tuple1))
        print(tuple2,type(tuple2))
        dict2=json.loads(dict1)
        print(dict2,type(dict2))
        >>>[1, 2, 3] <class 'list'>
        (44, 33, 22) <class 'tuple'>
        {'name': 'amwkvi', 'age': 18} <class 'dict'>
        
      2. json.load(obj,文件句柄):操作对象为文件,将从文件中读取出来的内容反序列化成相应的数据格式。

        with open('a.txt', encoding='utf-8') as f1:
            res = json.load(f1)
            print(res, type(res))
        >>>['abc', 112233, True, 3.23] <class 'list'>
        
    • jons文件通常是一次性写,一次性读,使用另外的方法可以实现多次写,多次读。

      以上例子中对文件的操作时,一次性读取多个数据会出错,所以一般还是用dumps和loads配合文件句柄对文件按行或者数据段进行操作,例:

      import json
      
      with open('a.txt', mode='wt', encoding='utf-8') as f:
          f.write(json.dumps(['abc', 112233, True, 3.23]) + '\n')		# 按行写入数据
          f.write(json.dumps({'name': 'amwkvi', 'age': 18}) + '\n')	# 每行后面加换行符
      
      with open('a.txt', encoding='utf-8') as f1:
          for line in f1:		# 用遍历文件句柄的方法对文件内容进行操作
              res = json.loads(line.strip())		# 将每一行结尾的换行符去年再进行反序列化
              print(res, type(res))
      ----------运行结果-----------
      ['abc', 112233, True, 3.23] <class 'list'>
      {'name': 'amwkvi', 'age': 18} <class 'dict'>
      
  6. pickle模块:将python中所有的数据类型转换成字节串(序列化过程),或将字节串转换成python中的数据类型(反序列化过程)。

    • 序列化过程:pickle.dumps()、pickle.dump()
    • 反序列化过程:pickle.loads()、pickle.load()

      以上方法使用与json没有区别,例:

      import pickle
      
      bys1 = pickle.dumps((1, 2, 4, 'abc'))
      tup1 = pickle.loads(bys1)
      print(tup1, type(tup1))
      >>>(1, 2, 4, 'abc') <class 'tuple'>		# pickle支持元组
      bys2 = pickle.dumps(set('aaaaamwkvi'))
      set1 = pickle.loads(bys2)
      print(set1, type(set1))
      >>>{'a', 'w', 'k', 'v', 'i', 'm'} <class 'set'>		# pickle支持集合
      
    • pickle.dump()和pickle.load()对于文件的操作方法也是和json一样,和json区别是可以多次写入多次读取。但是在实际应用当中,还是只会用到一次写入一次读取而已,因为并不知道前面写入了几次。

      with open('a.txt',mode='wb') as f:,操作文件时候mode需要用b类型,因为pickle序列化结果是字节。
  7. json和pickle的特点与区别:

    • json:

      1. 不是所有的数据类型都可以转化,转化结果是字符串。
      2. json.dump()和json.load()不能多次对同一个文件序列化。
      3. json转化的数据可以跨语言。
    • pickle:

      1. 所有的python类型都能序列化,转化结果是字节串。
      2. pickle.dump()和pickle.load()可以多次对同一个文件序列化。
      3. pickle转化的数据不可以跨语言。
  8. hashlib模块:

    这里面封装了一些用于加密的类。

    加密的目的:用于判断和验证,而并非解密。

    • 案例:验证用户名的密码是否匹配,但存于数据库中的密码又不可以明文保存;
    • 验证:给第一次创建的密码数据加密,用一另个数据加密的结果和第一个加密结果对比,如果结果相同,说明密码原文相同,如果不同,说明密码原文不同。

    特点:

    1. 把一个很大的数据,切分成不同的小块,分别对不同的块进行加密,再汇总的结果,和直接对整体数据进行加密的的结果是一致的。
    2. 单向加密,不可逆。
    3. 原始数据的一点小变化,将导致结果的非常大的差异,“雪崩”效应。

    加密算法的使用步骤:

    1. 获取一个加密方法(md5/sha1/shake等);
    2. 调用该算法的update()方法对对象进行加密,update方法可以调用多次;
    3. 调用该算法的hexdigest()方法获取加密后的结果,或digest()方法获取字节串的加密结果。

    举例:

    import hashlib
    m = hashlib.md5()  					# 获取一个加密对象
    m.update(b'abc')  					# 加密对象需要以字节形式导入
    res = m.hexdigest()  				# 获取加密的结果
    print(res)  						# 加密的结果是字符串
    m.update('abc中文'.encode('utf-8'))  # 加密对象中如果有中文字符,需要转化为字节类型
    res = m.hexdigest()
    print(res)
    >>>	900150983cd24fb0d6963f7d28e17f72
    	bb33ac3c7ccefffd55fabfd949dd8d49
    
    • 不同加密算法的最明显区别在于加密后结果的长度不同,长度越长,加密过程耗时越长。

    • 使用加密算法时,可以在创建加密对象步骤中直接将对象进行加密,而不通过update方法,最终结果是一致的。

      m = hashlib.md5()
      m.update(b'abc')
      m.update(b'def')
      print(m.hexdigest())		
      m = hashlib.md5(b'abcdef')		# 在创建加密方法的时候直接进行加密
      print(m.hexdigest())			# 直接获取加密结果
      >>>e80b5017098950fc58aad83c8c14978e		
         e80b5017098950fc58aad83c8c14978e		# 两次加密结果相同
      
  9. collections模块:

    这里面包含一些可以自定义的“容器”类数据。

    • namedtuple():命名元组,定义一个tuple的子类。

      可以使用这个方法定义一个自己的类,类的结构和说明都可以自己写,自定义的类等同于“int、str、list、dict”等结构体。

      自定义的类名,建议使用首字母大写形式,便于区分系统内置的一些模块名。自定义类的元素可以通过属性直接访问,也可以通过索引方式访问

      from collections import namedtuple
      
      Rectangle = namedtuple('这是一个描述长方形长和宽的类', ['length', 'width'])
      f = Rectangle(12, 4)
      print(type(Rectangle))		# <class 'type'>
      print(type(f))				# <class '__main__.这是一个描述长方形长和宽的类'>
      print(f.length,f.width)		# 12 4	# 通过属性访问
      print(f[0],f[1])			# 12 4	# 通过索引访问
      
    • defaultdict():默认值字典,在读取不存在键的时候,会根据定义的“工厂方法”给这个不存在的键匹配一个默认值,并将这个不存在的键加入到字典中。
      from collections import defaultdict
      
      mydict=defaultdict(int,name='amwkvi',age=18)
      print(mydict)		# defaultdict(<class 'int'>, {'name': 'amwkvi', 'age': 18})
      print(mydict['car'])	# 0		# 在此工厂方法为int函数,所以直接取第一个值
      print(mydict)		# defaultdict(<function f at 0x0000026332421C18>, {'name': 'amwkvi', 'age': 18})
      
      工厂方法也可以使用自定义函数,但是需要注意自定义函数不能有参数,它的返回值即defaultdict的默认值。
      def f():				# 自定义一个没有参数的函数
          return 'Yamaha'		# 这个返回值即默认值字典的默认值
      
      myd = defaultdict(f, name='amwkvi', age=18)
      print(myd)	# defaultdict(<function f at 0x00000231EFF81C18>, {'name': 'amwkvi', 'age': 18})
      print(myd['car'])	# Yamaha
      print(myd)	# defaultdict(<function f at 0x00000231EFF81C18>, {'name': 'amwkvi', 'age': 18, 'car': 'Yamaha'})
      
    • Counter():计数器
      from collections import Counter
      
      count = Counter('adssddaaaaa')  # 定义统计对象
      print(count)  # 显示统计结果:Counter({'a': 6, 'd': 3, 's': 2})
      print(count.most_common(2))  # 显示统计结果的前2名: [('a', 6), ('d', 3)]
      print(sorted(count.elements()))  # 将统计结果进行转为可迭代对象,再排序输出:['a', 'a', 'a', 'a', 'a', 'a', 'd', 'd', 'd', 's', 's']
      
posted @ 2020-12-13 16:33  amwkvi  阅读(66)  评论(0编辑  收藏  举报