zoukankan      html  css  js  c++  java
  • 常用模块

    自定义模块:

    • 什么是模块:一个.py文件就是模块,节省代码,容易维护,组织结构更清晰

    • 模块的运行方式:

      • 脚本方式:直接用解释器执行,或者pycharm中右键运行。

      • 模块方式:被其他的模块导入,为导入他的模块提供资源(变量,函数定义,)

    常用的模块:

    • json 不同语言之间序列化

    • pickle pyton语言使用,支持序列化数据类型多

    • sys 与python解释器交互的,解决变量路径问题

    • os 文件目录操作,操作系统底层函数

    • hashlib 加密模块

    • time 时间模块

    • datetime 时间模块,查找之前之后时间使用的较多

    • rendom 取随机值

    • logging 记录日志

    • collections 定义特殊的数据类型

    • re 正则

    • subprocess 执行windows端命令

    模块的分类:

    • 内置模块:标准库,python解释器自带的,time,os,sys,等等200多种
    • 第三方库(模块):各种大神写的模块,通过pip install...安装的6000多种
    • 自己写的模块,自定义模块

    引用模块发生三件事:

    • 1,import haiyang将haiyang.py文件(变量,函数名)加载到内存
    • 2,在内存中创建一个以haiyang命名的名称空间
    • 3,通过haiyang.xx名称空间的名字.等方式引用此模块的名字(变量,函数名)

    引用多个模块:

    • import os
    • import sys #引用多个模块时,要逐行引用

    import haiyang:

    • 当我引用haiyang模块的时候,实际上将haiyang.py执行一遍,加载到内存
      通过import引用的模块,他有自己的独立名称空间,与当前执行文件没有关系。
      
      执行文件:02 模块 import
      被引用文件(模块):haiyang.py
      为模块起别名:
      import  haiyang as ab
      print(ab.name)
      

    from haiyang import *:

    • 示例1:被引用文件(模块)all进行限制引用者使用范围

    • 引用者:
      from haiyang import *
      
      模块:
      __all__ = ['name']
      name = "huhaiyang"
      
    • 工作中错误示例:

    • from haiyang import name:
      from haiyang import *
      相当于从haiyang模块的全局空间中将name变量与值得对应关系,复制到当前执行文件的全局空间中
      引用模块中的函数,如果此函数修改一些变量,这些变量还是从此模块中寻找,不会改变当前执行文件变量
      
      优点:调用更方便
      缺点:引用变量跟当前文件变量冲突
      

    py文件的两种功能:

    • 1.py文件的第一个功能:执行文件(承载代码)脚本,直接打印`__name__`返回`__main__`
      
      2.py文件的第二个功能:模块(被动执行文件),直接打印`__name__`返回模块名
      
      作用:当你在被执行文件中,引用模块后,返回的是模块名,模块中进行了`if __name__ == '__main__':`
      判断的话,被执行者是不会执行此函数(控制函数自动调用),模块中可以进行测试代码    
      

    寻找一个模块的路径:

    • 内存中 >>> 内置模块 >>> sys.path
    • 只要这三个地方存在,就可以进行加载这个模块

    不同目录加载模块;

    • 将路径加载到sys.path中,以绝对路径导入。

    • import sys
      sys.path.append(r'E:\Python-学习\')
      import haiyang
      
      print(haiyang.name)
      

    包的使用:

    • 一个文件其实就是有个包

    • 创建一个包 new-package,会自行创建一个·__init__文件·

    • 创建包过程:

      • 1.将该aaa包内__init__.py文件加载到内存

      • 2.创建一个以aaa,命名的名称空间

      • 3.通过aaa. 的方式引用__init__的所有名字

    • 首先,无论在哪里引用模块,import或者from .. import..

    • 最开始的模块或者包的内存,每只sys,path中能找到的

    • 直接import 为了让我们会使用包里面的__init__

    • import 导入包以及包内的功能:

      • 示例1:简单的包引用

      • bolg
        |____ aaa
        |    |__ __init__.py   #from aaa import m1
        |    |__ m1.py         #定义函数func
        |
        |____ run.py         #aaa.m1.func()
        
        aaa目录文件m1 定义func函数:
        aaa目录__init__文件中定义:from aaa import m1
        
        import aaa
        #1.在执行文件写入import aaa
        #2.aaa的__init__里面写入 from aaa import m1
        #3.然后执行aaa.m1.a
        
        aaa.m1.func()
        
      • 示例2:多层目录引用__init__

      • #在当前文件中,引用aaa包下的bbb包的变量name
        #1.在执行文件写入import aaa
        #2.aaa的__init__里面写入 from aaa import bbb
        #3.bbb的__init__里面写入一个变量 name ="海洋"
        #4.然后执行aaa.bbb
        
        import aaa
        print(aaa.bbb.name)
        
      • 示例3:多层目录引用变量

      • bolg
        |____aaa
        |    |__bbb
        |    |  |__ __init__.py   #相对from ..bbb import m3 或者 from .mb import func3
        |    |  |__ m3.py         #func3函数
        |    | 
        |    |__ __init__.py      #from aaa import bbb/from aaa import m1
        |    |__ m1.py            #func1函数
        |    |__ m2.py
        |
        |____ run.py
        
        #在当前文件中,引用aaa包目录下的bbb包的变量name
        #1.在执行文件写入import aaa
        #2.在aaa的__init__里面写入 from aaa import bbb (bbb包里面的__init__里面可以引用)
        #3.在bbb包的__init__写入 from  aaa.bbb import m3
        #4.然后执行aaa.bbb.m3.func3()
        
        import aaa.bbb
        aaa.bbb.m3.func3()  #调用aaa下bbb下m3
        aaa.bbb.func3()     #init直接引用func3函数时不用加mb
        aaa.m1.func1()      #调用aaa目录下的m1
        
    • from ... import .... 导入包以及包内的功能

      • 这种方式不用设置__init__文件

      • # from a.b.c import d.e.f
        # c的前面必须是个包
        # import 的后面一定是名字,并且不能再有点
        
        #第一种直接引用目录文件下的变量
        from  aaa.bbb.m2 import  func1
        func1()
        
        #第二种直接引用目录下的文件
        from aaa.bbb import m2
        m2.func1()
        
        

    • 模块划整一个包:

      • # 由于nb模块增加了很多很多功能,所以我们nb这个文件就要划整一个包,
        # 无论对nb模块有任何操作,对于使用者来说不应该改变,极少的改变对其的调用.
        bolg
        |____ nb
        |    |__ __init__.py 
        |    |__ m1.py        #函数f1,f2
        |    |__ m2.py       #函数f3
        |
        |____ run.py
        
        __init__.py存放:
        from nb.m1 import f1,f2
        from nb.m2 import f3
        
        执行文件:
        run.py  执行:nb.f1() nb.f2() nb.f3()
        
        
    • 多层目录引用:

      • bolg         #第一层
        |____NB      #第二层
        |    |__dsb  #第三层
        |    |    |__ly       #f3
        |    |__ __init__.py  
        |    |__ m1.py        #f1函数 
        |    |__ m2.py        #f2函数
        |
        |____ run.py
        
        #__init__存放
        from .m1 import f1
        from .m2 import f2
        from .dsb.ly import f3
        
        #执行文件:
        #第一种运行方法,将目录添加到sys.path
        # import sys
        # sys.path.append(r'E:\相对导入绝对导入\bolg')
        import NB as nb
        nb.f1()
        nb.f2()
        nb.f3
        
        #第二种运行方法:
        import dir.NB as nb
        nb.f1()
        nb.f2()
        nb.f3()
        
        

    模块使用:

    序列化模块:

    • 序列化模块:将一种数据结构 (list,dict) 转化成一个特殊的序列(特殊的字符串,bytes)的过程

      ​ 并且还可以翻转回去。

    • 为什么要有序列化:

      • str(list)字符串存储到文件中,读取出来,反转不回去
      • 凡是数据通过网络传出去最终格式必须是bytes类型
    • json模块:

    • 支持python数据结构有限:int str list dict tuple bool none float

    • pickle模块:

      • 支持python中所有的数据类型以及对象,只能是python语言中使用的
    • shevle模块:

      • 只能是文件存取

    json模块方法:

    • dumps序列化: loads 反序列化(主要用于网络传输和多文件存取)

    • import json
      dic = {'username':'海洋'}
      ret = json.dumps(dic)
      print(ret)
      
      ret1 = json.loads(ret)
      print(ret1)
      
      特殊参数
      import json
      dic = {'username': '海洋', 'password': 123,'status': False}
      ret = json.dumps(dic,ensure_ascii=False,sort_keys=True)
      ret1 = json.loads(ret)
      
      print(ret,type(ret))
      print(ret,type(ret1))
      
      #文件存取:
      import json
      dic = {'username': '海洋', 'password': 123,'status': False}
      
      with open("jsontest",encoding='utf-8',mode='w') as f1:
           ret = json.dumps(dic)
           f1.write(ret)
      
      with open("jsontest", encoding='utf-8') as f1:
          ret2 = json.loads(f1.read())
          print(ret2)
      
      
    • 多个文件存储使用dumps:

    • import json
      dic1 = {'username': '海洋', 'password': 123,'status': False}
      dic2 = {'username': '俊丽', 'password': 123,'status': False}
      dic3 = {'username': '宝宝', 'password': 123,'status': False}
      
      with open("jsontest",encoding='utf-8',mode='a') as f1:
           f1.write(f"{json.dumps(dic1)}\n{json.dumps(dic2)}\n{json.dumps(dic3)}\n")
      
      with open("jsontest", encoding='utf-8') as f1:
          for line in f1:
              ret = json.loads(line)
              print(ret,type(ret))
      
      
    • dump load:只能用于单个数据的存储文件(不常用 )

    • #不需要先转换字符串,节省一些代码
      import json
      dic = {'username': '海洋', 'password': 123,'status': False}
      
      with open("jsontest",encoding='utf-8',mode='w') as f1:
           json.dump(dic,f1)
      
      with open("jsontest", encoding='utf-8') as f1:
          dic1 = json.load(f1)
          print(dic1)
      

    pickle模块:

    • dumps,loads:(只能是网络传输)

    • import pickle
      l1 = ["海洋",'俊丽',888]
      
      l2 = pickle.dumps(l1)
      l3 = pickle.loads(l2)
      print(l2)
      print(l3)
      
    • dump load:(只能数据结构存取文件)

    • import pickle
      l1 = ["海洋",'俊丽',888]
      
      with open("jsontest",mode='wb') as f1:
          pickle.dump(l1,f1)
      
      with open("jsontest",mode='rb') as f2:
          ret = pickle.load(f2)
          print(ret,type(ret))
      
    • dump load:(pickle 多个文件写入)

    • import pickle
      l1 = ["海洋",'俊丽',888]
      l2 = ["海洋",'俊丽',888]
      l3 = ["海洋",'俊丽',888]
      
      with open("jsontest",mode='wb') as f1:
          pickle.dump(l1,f1)
          pickle.dump(l2,f1)
          pickle.dump(l3,f1)
      
      with open("jsontest",mode='rb') as f2:
          ret1 = pickle.load(f2)
          ret2 = pickle.load(f2)
          ret3 = pickle.load(f2)
          print(ret1,ret2,ret3,type(ret1))
      
    • pickle 对象写入文件:

    • #写入
      with open(settings.register_student,mode="ab") as f3:
           pickle.dump(obj_write,f3)
      #读取
      with open(settings.register_student,mode="rb") as f4:
            while 1:
                 try:
                     ret1 = pickle.load(f4)
                      yield ret1
                 except Exception:
                      break
      
      

    sys模块:(路径)

    • import sys
      print(sys.path)      #获取当前路径
      print(sys.version)   #获取python版本
      1
      for i in range(3):
          print(i)
      sys.exit() #主动退出
      exit()  
      print(111)
      
      sys.path.append(路径)  #与python解释器进行交互,解决变量路径问题
      

    os模块:(文件,目录)

    • 工作目录:当前目录,父级目录(上层目录)

    • #操作系统底层函数的方法
      import os
      # 查看当前工作目录和切换目录
      print(os.getcwd())
      print(os.chdir("路径"))  #切换目录,相当于shell的cd
      print(os.curdir)        #返回当前目录名
      print(os.pardir)        #返回当前目录的父目录字符串名
      
      
      # 和文件夹相关
      os.makedirs("haiyang/haha")     #在当前目录生成目录可以生成多层,类似mkdir -p
      os.removedirs('目录')            #若目录为为空则删除,不为空删除不了
      os.mkdir('目录')                 #生成单级目录
      os.rmdir('目录')                 #删除单级空目录,为空无法删除
      print(os.listdir('haiyang'))    #列出指定目录下的所有文件和子目录,以列表的方式
      
      
      # 和文件相关
      os.remove("file")               #删除文件
      os.rename('旧文件','新文件')      #重命名文件
      print(os.stat('jsontest'))      #获取文件/目录信息
      
      
      # path和路径相关
      # print(os.path.abspath('jsontest'))   #返回当前的绝对路径
      
      #将当前的绝对路径转化为列表,前面为路径,后面为文件名
      # print(os.path.split(os.path.abspath('jsontest')))  
      # print(__file__)    #动态获取当前文件的绝对路径
      
      # 获取当前文件的爷爷级目录
      # print(os.path.dirname(os.path.abspath('jsontest')))   #获取父级目录
      # print(os.path.basename(os.path.abspath('jsontest')))   #返回一个路径最后的文件名
      
      
      # 判断路径
      # os.path.join("路径1",'路径2')   #将多个路径拼接组合
      # print(os.path.isfile(os.path.abspath('jsontest')))  #判断路径是否是文件  在返回True
      # print(os.path.isdir(os.path.abspath('jsontest')))   #判断路径是否目录  在返回True
      # print(os.path.exists(os.path.abspath('jsontest')))  #判断当前路径是否存在  在返回True
      # print(os.path.isabs(os.path.abspath('jsontest')))   #判断是否是绝对路径   在返回True
      
      
      # print(os.path.getatime('文件或者目录'))               #查看文件或者目录最后访问时间
      # print(os.path.getmtime('文件或者目录'))               #查看文件或者目录最后修改时间
      # print(os.path.getsize("文件或者目录"))                #查看文件或者目录大小
      
      

    hashlib模块:(加密)

    • 加密模块,摘要算法,散列算法,等等

    • 加密过程:

      • 1,将一个bytes类型的数据,通过hashlib进行加密返回,一个等长度的16进制数字
      • 2,过程不可逆
      • 3,相同的bytes类型的数据通过相同的加密方法得到的数据绝对相同
      • 4,不相同的bytes类型的数据通过相同的加密方法得到的数据也绝对不相同
    • 加密示例:

      • import hashlib
        ret = hashlib.md5()
        ret.update('海洋'.encode('utf-8'))
        print(ret.hexdigest())
        
        
    • 加盐示例:

      • import hashlib
        ret = hashlib.md5("俊丽".encode('utf-8'))   #俊丽盐
        ret.update('海洋'.encode('utf-8'))
        print(ret.hexdigest())
        
        
    • 动态加盐示例:

      • import hashlib
        username = input("输入用户名:").strip()
        password = input('输入密码').strip()
        ret = hashlib.md5(username.encode('utf-8'))   #动态的用户名
        ret.update('海洋'.encode('utf-8'))
        print(ret.hexdigest())
        
        
    • sha系列加密:

      • #sha系列:安全系数高,耗时高
        import hashlib
        username = input("输入用户名:").strip()
        password = input('输入密码').strip()
        ret = hashlib.sha3_512(username.encode('utf-8'))
        ret.update('海洋'.encode('utf-8'))
        print(ret.hexdigest())
        
        
    • 文件校验:

      • import hashlib
        def md5_file(path):
            ret = hashlib.md5()
            with open(path,mode='rb') as f1:
                while 1:
                    content = f1.read(1024)   #每次读取文件
                    if content:
                        ret.update(content)
                    else:
                        return ret.hexdigest()
        
        print(md5_file('python-3.7.4rc1-embed-win32.zip'))
        
        

    time模块:(时间)

    • 三种形式:

      • 1,时间戳:time.time() 格林威治时间,时差,计时 1561696705.6334207
      • 2,人类看的懂的时间,格式化时间, 2019-6-28 12:00
      • 3,结构化时间:python语言使用的,解释器使用的 time.struct_time(tm_year=2019, .....
    • 格式化时间:

      • #%Y年 %m月 %d日  %H时  %M分 %S秒
        
        print(time.strftime("%Y-%m-%d %H:%M:%S" ))     #字符串类型的格式化时间
        print(time.strftime("%Y-%m-%d %H:%M:%S %A" ))  #字符串类型的格式化时间
        
        
    • 时间戳转换格式化时间

      • timetamp = time.time()
        st = time.localtime(timetamp)
        # print(st)
        time1 = time.strftime('%Y/%m/%d %H:%M:%S',st)
        print(time1)
        
        
    • 格式化时间转化成时间戳

      • import time
        ft = time.strftime('%y/%m/%d %H:%M:%S')
        # print(ft)
        st = time.strptime(ft,'%y/%m/%d %H:%M:%S')
        timestamp = time.mktime(st)
        print(timestamp)
        
        

    datetime模块:

    • 查找之前的时间:

      • import datetime
        time1 = datetime.datetime.now()        #现在的时间
        print(datetime.datetime.now() + datetime.timedelta(weeks=3))  #三周前
        
        print(current_time.replace(year=1977))   #调整到指定年月
        
        
    • 将时间戳转化成时间:

      • print(datetime.date.fromtimestamp(1232132131))
        
        

    random模块:

    • 随机取值

      • import random
        #随机字符串随机发红包时使用
        print(random.random())           #大于0小于1之间的小数
        print(random.uniform(1,6))       #随机取1-6的小数
        print(random.randint(1,5))       #1-5随机取值
        print(random.randrange(1,10,2))  #顾头不顾尾
        
        print(random.choice(['海洋','俊丽','宝宝']))  #可迭代对象随机取列表值
        print(random.sample(['海洋','俊丽','宝宝'],2)) #可迭代对象随机取列表值,2选两个
        
        item = [i for i in range(10)]   #原列表打乱顺序
        random.shuffle(item)
        print(item)
        
        

    logging模块:

    • 系统日志:记录服务器的一些重要信息,监控系统,网卡流量,记录操作信息等等。
    • 网站日志:访问异常,卡顿,网站一些板块,受欢迎程度,访问量,点击率,等等。
    • 错误日志:开发人员在开发项目中利用日志进行排错,排除一些避免不了的错误,辅助开发
    • 记录用户信息日志:用户的消费习惯,新闻偏好等等(数据库解决)

    • 三个版本:
      • 1.low版 (简易版)
      • 2.标配版(标配版)
      • 3.旗舰版(项目中使用的,Django项目)

    • low版:

      • #缺点:文件与屏幕输出只能选择一个
        
        import logging
        logging.basicConfig(                   #设置级别才会出现info和debug
            # level=logging.DEBUG,
            level=30,                          #设置日志级别,可以调整
            format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', #日志格式
            filename=r'test.log',            #写入日志
        )
        logging.debug('调试模式')         #调试
        logging.info('信息信息')          #信息
        logging.warning('警告信息')       #警告
        logging.error('错误信息')         #错误
        logging.critical('严重错误')      #关键
        
        
    • 标配版:

      • #文件和屏幕都可以输入
        import logging
        
        logger = logging.getLogger()                                #创建一个logger对象
        fh = logging.FileHandler('标配版.log',encoding='utf-8')      #创建文件对象
        sh = logging.StreamHandler()                                #创建屏幕对象
        
        #创建显示格式:
        formatter = logging.Formatter('%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s')
        fh.setFormatter(formatter)       #绑定显示格式
        sh.setFormatter(formatter)
        
        logger.addHandler(fh)            #logger对象添加多个fh,ch对象
        logger.addHandler(sh)
        
        # logger.setLevel(10)            #总开关,不写默认级别30,先写总开关
        # fh.setLevel(30)
        # sh.setLevel(10)
        
        logging.debug('调试模式')         #调试
        logging.info('信息信息')          #信息
        logging.warning('警告信息')       #警告
        logging.error('错误信息')         #错误
        logging.critical('严重错误')      #关键
        
        
    • 旗舰版:

      • 自定制(通过字典的方式)日志

      • 轮转日志的功能

      • import logging.config    #引用配置文件/模块
        
        # 定义三种日志输出格式 开始
        standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                          '[%(levelname)s][%(message)s]'   #其中name为getlogger指定的名字
        simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s'   #级别/时间/信息
        # 定义日志输出格式 结束
        
        
        #写入日志路径和日志名称
        logfile_name = 'log1.log'
        logfile_path = r"E:\Python-学习\作业\23期\day19-包的导入-login日志\日志\log1.log"
        
        
        # log配置字典
        #LOGGING_DIC第一层key不能改变
        LOGGING_DIC = {
            'version': 1,                                 #版本号
            'disable_existing_loggers': False,            #固定写法
            'formatters': {                               #日志格式
                'standard': {                             #标准格式
                    'format': standard_format
                },
                'simple': {                               #简单格式
                    'format': simple_format
                },
            },
            'filters': {},                                #过滤
            'handlers': {
                #打印到终端的日志
                'sh1': {                                  #终端日志打印到屏幕
                    'level': 'DEBUG',                     #debug开始打印
                    'class': 'logging.StreamHandler',
                    'formatter': 'simple'
                },
                #打印到文件的日志,收集info及以上的日志
                'staff_fh': {                                              #写到文件信息
                    'level': 'DEBUG',
                    'class': 'logging.handlers.RotatingFileHandler',       # 保存到文件
                    'formatter': 'standard',                               # 选择复杂的格式
                    'filename': logfile_path,                              # 日志文件
                    'maxBytes': 3000,        # 日志大小字节 5M1024*1024*5
                    'backupCount': 5,
                    'encoding': 'utf-8',     # 日志文件的编码,再也不用担心中文log乱码了
                },
                'boss': {  # 写到文件信息
                    'level': 'DEBUG',
                    'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                    'formatter': 'standard',                          # 选择复杂的格式
                    'filename': logfile_path,                         # 日志文件
                    'maxBytes': 3000,  # 日志大小字节 5M1024*1024*5
                    'backupCount': 5,
                    'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
                },
            },   #句柄
            'loggers': {
                #logging.getLogger(__name__)拿到的logger配置
                '': {
                    'handlers': ['staff_fh', 'sh1','boss'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                    'level': 'DEBUG',
                    'propagate': True,        # 向上(更高level的logger)传递
                },
            },                 #产生几个log
        }
        
        
        def load_my_logging_cfg(task_id):
            logging.config.dictConfig(LOGGING_DIC)    #通过你写的字典方式配置日志/第一步
            logger = logging.getLogger(task_id)       # 生成一个log实例/
            return logger
        
        def login():
            logging1 = load_my_logging_cfg("登录功能")
            logging1.info("海洋登录信息")
        
        def transfer():
            logging2 = load_my_logging_cfg("转账功能")
            logging2.info("张三给李四转账成功")
        
        login()
        transfer()
        
        
    • 旗舰版日志(函数):

      • import logging.config  
        def student_log(info,task_id):
            standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
                              '[%(levelname)s][%(message)s]'
            simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        
            logfile_name = "student_info.log"
            logfile_path = os.path.join(settings.register_logs,logfile_name)
        
            LOGGING_DIC = {
                'version': 1,
                'disable_existing_loggers': False,
                'formatters': {
                    'standard': {
                        'format': standard_format
                    },
                    'simple': {
                        'format': simple_format
                    },
                },
                'filters': {},
                'handlers': {
                    'staff_fh': {
                        'level': 'DEBUG',
                        'class': 'logging.handlers.RotatingFileHandler',
                        'formatter': 'standard',
                        'filename': logfile_path,
                        'maxBytes': 3000000,
                        'backupCount': 5,
                        'encoding': 'utf-8',
                    },
                },   #句柄
                'loggers': {
                    '': {
                        'handlers': ['staff_fh'],
                        'level': 'DEBUG',
                        'propagate': True,
                    },
                },
            }
        
            logging.config.dictConfig(LOGGING_DIC)   #字典的配置信息
            logger = logging.getLogger(task_id)      #生成一个log实例
            logger.info(info)                        
            
        common.student_log(f"{self.name}创建了课程{ke_name}","创建课程功能") #调用日志
        
        

    collections模块:

    • 给我们提供一下python数据类型,比较特殊的数据类型,出奇制胜

    • 1.namedtuple: 生成可以使用名字来访问元素内容的tuple(自定义类型)

      • #命名元祖
        from collections import namedtuple
        Point = namedtuple("point",['x','y'])  #"point" 自定义类型
        print(type(Point))
        p = Point(1,2)         #键值对存储
        print(type(p))
        print(p)
        print(p[0])		       #索引取值
        
        
    • 2.deque: 双端队列,类似于列表的一种容器性数据,插入元素,删除元素,效率高

      • from collections import deque
        #从后面添加
        q = deque(['a',1,'c','d'])
        q.append('e')
        print(q)
        
        #在前面添加
        q.appendleft("66")
        q.appendleft("77")
        q.pop()       #默认删除最后一个
        q.popleft()   #默认删除最前面的
        print(q)
        
        #按照索引删
        def q[2]
        print(q)
        
        
    • 3.Counter: 计数器,主要用来计数

      • from collections import  Counter
        
        c = Counter("sdagdjashdaskd")
        print(c)
        
        
    • 4.OrderedDict: 有序字典

      • from collections import OrderedDict
        od = OrderedDict()
        od['z'] = 1
        od['y'] = 2
        od['x'] = 3
        print(od.keys())
        
        
    • 5.defaultdict 带有默认值的字典

      • from  collections import defaultdict
        #not in方式
        l1 = [11,22,33,44,55,77,88,99]
        dic = {}
        for i in l1:
            if i < 66:
                if "key1" not in dic:
                    dic['key1'] = []
                dic['key1'].append(i)
            else:
                if 'key2' not in dic:
                    dic['key2'] = []
                dic['key2'].append(i)
        print(dic)
        
        #defaultdict方式
        l1 = [11,22,33,44,55,77,88,99]
        dic = defaultdict(list)
        for i in l1:
            if i < 66:
                dic['key1'].append(i)
            else:
                dic['key2'].append(i)
        print(dic)
        
        

    re模块:

    • 正则表达式:从字符串中找出你想要的字符串

      • 在于对你想要得找个字符串进行一个精确的描述
      • 使用在爬虫中
    • 单个字符匹配:
      • #\W与w
        #\w 数字字母下划线中文
        #\W 非数字字母下划线中文
        print(re.findall("\w",'海洋jx 12*() _'))  #['海', '洋', 'j', 'x', '1', '2', '_']
        print(re.findall("\W",'海洋jx 12*() _'))  #[' ', '*', '(', ')', ' ']
        
        #\s 空格 换行符
        #\S 非空格 换行符
        print(re.findall('\s','海洋haiyang*(_ \t \n'))  #[' ', '\t', ' ', '\n']
        print(re.findall('\S','海洋haiyang*(_ \t \n'))  #['海', '洋', 'h', 'a'.....
        
        #\d  匹配数字 \d\d匹配两个字符
        #\D  匹配非数字 \d\d匹配两个字符
        print(re.findall('\d','12345 hai*(_'))  #['1', '2', '3', '4', '5']
        print(re.findall('\D','12345 hai*(_'))  #[' ', 'h', 'a', 'i'.....
        
        #\A  匹配以什么开头
        # ^
        print(re.findall('\Ahello','hello 胡海洋 -_- 666'))    #['hello']
        print(re.findall('^hello','hello 胡海洋 -_- 666'))     #['hello']
        
        # \Z、\$ 匹配以什么结尾
        print(re.findall('666\Z','hello 海洋 *-_-* \n666'))   #['666']
        print(re.findall('666$','hello 海洋 *-_-* \n666'))    #['666']
        
        # \n 与 \t 匹配\n 与 \t
        print(re.findall('\n','hello \n 海洋 \t*-_-*\t \n666'))  # ['\n', '\n']
        print(re.findall('\t','hello \n 海洋 \t*-_-*\t \n666'))  # ['\t', '\t']
        
        
    • 元字符匹配:
      • #. ? * + {m,n} . * .*?
        #. 匹配任意字符
        #如果匹配成功,光标则移动到下一位
        #如果为匹配成功,光标向下移动一位
        print(re.findall('a.b', 'aabbb,ab aab a*b aaab a海b')) ['aab', 'aab',....
                                                               
        #? 匹配0个或者1个 由左边字符定义的片段,不是ab 就是b(不匹配a)
        print(re.findall('a?b', 'aabbb,ab aab a*b aabb a海b' ))
                                                               
        # * 匹配0个或者多个左边字符表达式。 满足贪婪匹配 
        print(re.findall('a*b', 'ab aab aaab abbb'))
        print(re.findall('ab*', 'ab aab aaab abbbbb'))            
                                                               
        # + 匹配1个或者多个左边字符表达式。 满足贪婪匹配 
        print(re.findall('a+b', 'ab aab aaab abbb'))  # ['ab', 'aab', 'aaab', 'ab']       
        
        # {m,n}  匹配m个至n(n能取到)个左边字符表达式。 满足贪婪匹配
        print(re.findall('a{2,4}b', 'ab aab aaab aaaaabb'))  # ['aab', 'aaab']
                                               
        
        
    • 贪婪匹配:
      • #.*  贪婪匹配 从头到尾,必须要a开头b结尾,中间全部匹配,贪婪匹配
        #.换行符不匹配
        print(re.findall('a.*b', 'ab aab a*()b'))  # ['ab aab a*()b']
        #换行符也可以匹配
        print(re.findall('a.*b', 'ab aab a*()b',re.DOTALL))  # ['ab aab a*()b']
        
        
    • 非贪婪匹配:
      • # .*? 此时的?不是对左边的字符进行0次或者1次的匹配,
        # 而只是针对.*这种贪婪匹配的模式进行一种限定:告知他要遵从非贪婪匹配 推荐使用!
        # a到b就匹配也就是0个或者多个
        print(re.findall('a.*?b', 'ab a1b a*()b, aaaaaab'))  # ['ab', 'a1b', 'a*()b']
        
        # []: 括号中可以放任意一个字符,一个中括号代表一个字符
        print(re.findall('[ab]', 'a1b a3b aeb a*b arb a_b'))             #匹配里面的a或者b
        print(re.findall('a[abc]b', 'aab abb acb adb afb a_b'))          #匹配前后加[]里面一个
        print(re.findall('a[0-9]b', 'a1b a3b aeb a*b arb a_b'))           #数字
        print(re.findall('a[a-z]b', 'a1b a3b aeb a*b arb a_b'))           #小写
        print(re.findall('a[a-zA-Z]b', 'aAb aWb aeb a*b arb a_b'))        #大小写
        print(re.findall('a[0-9][0-9]b', 'a11b a12b a34b a*b arb a_b'))  #符合a[][]b里面的两个数字
        print(re.findall('a[*-+]b','a-b a*b a+b a/b a6b'))                #取符号
        
        #当你想匹配- 时,要把他放在[]里面的最前面
        print(re.findall('a[-*$]b','a-b a$b a*b'))
        
        #^ 在[]中表示取反的意思.
        print(re.findall('a[^0-9]b', 'a1b a3b aeb a*b arb a_b'))
        
        
        
    • 分组:
      • #()分组取
        s = 'haiyang_sb junli_sb baobao_sb haha_nb xixi_sb dd_sb'
        print(re.findall('(\w+)_sb',s))
        
        #|匹配左边或者右边
        print(re.findall('haiyang|junli', 'haiyangjunli'))
        
        
        #先把分组去掉筛选,在返回ies和y
        print(re.findall('compan(y|ies)',
                         'Too many companies have gone bankrupt, and the next one is my company'))
        
        #(?):将全部的内容返回,而不是将组内的内容返回,companies|company道理一样
        print(re.findall('compan(?:y|ies)',
                         'Too many companies have gone bankrupt, and the next one is my company'))
        
        
        
        
    • re常用方法:
      • findall 全部找到以列表返回

      • print(re.findall('a', 'alexwusirbarryeval'))  # ['a', 'a', 'a']
        
        

      • search 找到第一个符合条件的字符串就返回,通过.group()返回

      • print(re.search('sb|alex', 'alex sb sb barry 日天'))
        print(re.search('alex', 'alex sb sb barry 日天').group())
        
        

      • match:None,从字符串开头匹配,如果第一个条件字符串符合规则则返回,否则返回none

      • print(re.match('barry', 'barry alex wusir 日天'))
        print(re.match('barry', 'barry alex wusir 日天').group())
        
        
      • split 分割 可按照任意分割符进行分割:

      • print(re.split('[ ::,;;,]','alex wusir,日天,太白;女神;肖锋:吴超'))
        
        
      • sub 替换:

      • print(re.sub('俊丽', '海洋', '俊丽是最好的'))
        
        
      • 自定义obj:

      • obj=re.compile('\d{2}')
        
        print(obj.search('abc123eeee').group())  #12
        print(obj.findall('abc123eeee'))         #['12'],重用了obj自定义obj:
        
        
      • finditer 迭代器返回

      • ret = re.finditer('\d', 'ds3sy4784a')   #finditer返回一个存放匹配结果的迭代器
        print(ret)                               # <callable_iterator object at 0x10195f940>
        print(next(ret).group())                 #查看第一个结果
        print(next(ret).group())                 #查看第二个结果
        print([i.group() for i in ret])         #查看剩余的左右结果
        

    subprocess:

    • 调用示例:

      • #dir为调用的命令
        import subprocess
        
        obj = subprocess.Popen('dir',
                               shell=True,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE,
                               )
        
        print(obj.stdout.read().decode('gbk'))  # 正确命令
        print('error:',obj.stderr.read().decode('gbk'))  # 错误命令
        
  • 相关阅读:
    DTM DEM DSM 介绍
    VC自定义消息
    一句话设计模式基本原则
    抽空写了一个ICON图标的转换程序
    (转载)C# 中的委托和事件
    类的字段和静态字段的使用
    Command 对象总结
    使用 DataReader 检索数据的步骤
    分享一部电影
    C#处理ACCESS数据库
  • 原文地址:https://www.cnblogs.com/haiyang11/p/11091477.html
Copyright © 2011-2022 走看看