内容概要
  • configparser模块
  • hashlib模块
  • json与pickle模块
  • subprocess模块
  • logging模块
  • 猴子补丁
内容详细
  • configparser模块

    import configparser
    config = configparser.ConfigParser()
    config.read('test1.ini',encoding='utf-8')
    
    # # 1.获取sections
    # # print(config.sections())
    res = config.sections()
    print(res)
    # # 2.获取某一sections下的所有options
    # print(config.options('section1'))
    #
    # # 3.获取items
    # print(config.items('section1'))
    #
    # # 4.
    # res = config.get('section1','user')
    # print(res)
    
    # res = config.getint('section1','age')
    # print(res,type(res))
    #
    # res = config.getboolean('section1','is_admin')
    # print(res,type(res))
    
    res = config.getfloat('section1','salary')
    print(res,type(res))
    
  • hashlib模块

    # 1.什么是哈希hash
    #   hash一类的算法,该算法接受传入的内容,经过运算得到一串hash值
    #   hash值的特点:
    #       1)只要传入的内容一样,得到的hash值必然一样
    #       2)不能有hash值反解成内容
    #       3)不管传入的内容有多大,只要使用的hash算法不变,得到的hash值长度一定
    
    # 2.hash的用途
    #     用途1:特点2)用于密码密文传输与认证
    #     用途2:特点1)、3)用于文件完整性校验
    
    # 3.如何用
    import hashlib
    # m = hashlib.md5()
    # m.update('hello'.encode('utf-8'))
    # m.update('world'.encode('utf-8'))
    # res = m.hexdigest()
    # # 此时这里读出来的内容是'hello'+'world',也可以用update('helloworld')一下全部读出,有可能会导致内存溢出
    # print(res)  # fc5e038d38a57032085441e7fe7010b0
    
    # 模拟撞库
    # 1.先获取一个密文密码
    # m = hashlib.md5()
    # m.update('ycc1217'.encode('utf-8'))
    # # m = hashlib.md5('ycc1217'.encode('utf-8')) 等价于上面两行代码
    # res = m.hexdigest()
    # print(res)  # 557a08fe46e82567c1e99ab29ec2f3e2
    
    # 2.撞库
    # hash_pwd = '557a08fe46e82567c1e99ab29ec2f3e2'
    # guess_pwd = [
    #     'ycc1217',
    #     '1217ycc',
    #     'cc1217'
    # ]
    # dic = {}
    # for g in guess_pwd:
    #     res = hashlib.md5(g.encode('utf-8'))
    #     dic[g] = res.hexdigest()
    # for k,v in dic.items():
    #     if v == hash_pwd:
    #         print('撞库成功,明文密码是:%s'%k)
    #         break
    
    # 提升撞库的成本==>密码加盐
    import hashlib
    m = hashlib.md5()
    m.update('for'.encode('utf-8'))
    m.update('ycc'.encode('utf-8'))
    m.update('the'.encode('utf-8'))
    m.update('1217'.encode('utf-8'))
    m.update('dream'.encode('utf-8'))
    res = m.hexdigest()
    print(res)
    
  • json与pickle模块

    # 1.什么是序列化&反序列化
    #   序列化指的是把内存的数据类型转换成一个特定的格式的内容
    #   该格式的内容可用于存储或者传输给其他平台使用
    
    # 内存中的数据类型--->序列化--->特定的格式(json或pickle)
    # 内存中的数据类型<---反序列化<---特定的格式(json或pickle)
    
    # 土办法
    # {'aaa':111}--->序列化str('{'aaa':111}')---->'{'aaa':111}'
    # {'aaa':111}<---反序列化eval('{'aaa':111}')<----'{'aaa':111}'
    
    # 2.为何要序列化:
    #    序列化得到结果=>特定的格式的内容有两种用途
    #    1.可用于存储==>用于存档
    #    2.传输给其他平台使用==>跨平台数据交互
    #        python                java
    #        # 列表      特定的格式    数组
    
    # 强调:
    #       针对用途1的特定格式:可以是一种专用的格式=>pickle只有python可以识别
    #       针对用途2的特定格式:应该是一种通用、能够被所有语言识别的格式=>json
    
    # 3.如何序列化与反序列化
    import json
    #     # 示范一:
    #     # 序列化
    #     json_res = json.dumps([1,'aa',True,False])
    #     print(json_res,type(json_res))  # [1, "aa", true, false] <class 'str'>
    #
    #     # 反序列化
    #     l = json.loads(json_res)
    #     print(l,type(l))  # [1, 'aa', True, False] <class 'list'>
    
    #     示范二:
    # 序列化
    #     # 将序列化的结果写入文件的复杂方法
    #     with open('test.json',mode='wt',encoding='utf-8') as f:
    #         json_res = json.dumps([1,'aa',True,False])
    #         f.write(json_res)
    #
    #     # 将序列化的结果写入文件的复杂方法
    #     with open('test.json',mode='wt',encoding='utf-8') as f:
    #         json.dump([1,'aa',True,False],f)0
    
    # 反序列化
    #     从文件读取json格式的字符串进行反序列化操作的复杂方法
    #     with open('test.json',mode='rt',encoding='utf-8') as f:
    #         json_res1 = f.read()
    #         l = json.loads(json_res1)
    #         print(l,type(l))  # [1, 'aa', True, False] <class 'list'>
    #
    #     # 从文件读取json格式的字符串进行反序列化操作的简单方法
    #     with open('test.json',mode='rt',encoding='utf-8') as f:
    #         l = json.load(f)
    #         print(l,type(l))
    
    # json验证:json格式兼容的是所有语言通用的数据类型,不能识别某一语言的所独有的类型
    # json.dumps({1,2,3,4,5})  # TypeError: Object of type set is not JSON serializable
    
    # json强调:一定要搞清楚json格式,不要与python混淆
    # l = json.loads('[1,"aa",true,false]')
    # print(l[1])  # aa
    
    # l = json.loads('[1,'aa',true,false]')  # SyntaxError: invalid syntax  一定要双引号"aa"
    # print(l[1])
    
    # 了解
    # 在python解释器2.7与3.6后都可以json.loads(bytes类型),但唯独3.5不行
    # l = json.loads(b'[1,"aa",true,false]')
    # print(l)
    
    # res = json.dumps({'name':'嘻嘻嘻'})
    # print(res)  # {"name": "\u563b\u563b\u563b"}
    #
    # res1 = json.loads('{"name": "\u563b\u563b\u563b"}')
    # print(res1)  # {'name': '嘻嘻嘻'}
    
    
    # 4.pickle模块
    import pickle
    res = pickle.dumps({1,2,3,4,5})
    print(res,type(res))
    # b'\x80\x04\x95\x0f\x00\x00\x00\x00\x00\x00\x00\x8f\x94(K\x01K\x02K\x03K\x04K\x05\x90.' <class 'bytes'>
    
    s = pickle.loads(res)
    print(s,type(s))
    # {1, 2, 3, 4, 5} <class 'set'>
    
    # 了解
    # # coding:utf-8
    # import pickle
    #
    # with open('a.pkl',mode='wb') as f:
    #     # 一:在python3中执行的序列化操作如何兼容python2
    #     # python2不支持protocol>2,默认python3中protocol=4
    #     # 所以在python3中dump操作应该指定protocol=2
    #     pickle.dump('你好啊',f,protocol=2)
    #
    # with open('a.pkl', mode='rb') as f:
    #     # 二:python2中反序列化才能正常使用
    #     res=pickle.load(f)
    #     print(res)
    
    
  • subprocess模块

    import subprocess
    obj = subprocess.Popen('ls /',shell=True,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE
                           )
    print(obj)
    
    res = obj.stdout.read()
    print(res.decode('utf-8'))
    
    err_res = obj.stderr.read()
    print(err_res.decode('gbk'))
    
  • 猴子补丁

    # 安装ujson==》cmd==>pip3 install ujson
    import json
    import ujson
    
    def monkey_patch_json():
        json.__name__ = 'ujson'
        json.dumps = ujson.dumps
        json.loads = ujson.loads
    monkey_patch_json()  # 在入口文件运行
    # 将json替换成ujson(更好的功能)
    
    # 如果已经调用了大量的json,没事,这步操作能将其修改
    # 并且,此时,你看似调用的是json,其实调用的是ujson
    
    
    # import ujson as json  不行,名称空间不一样
    # 虽然能用,但是也得在每个文件内都改别名,且本质不一样
    
    • logging模块

      '''
      配置信息
      '''
      import os
      
      # 获取项目根目录路径
      BASE_PATH = os.path.dirname(os.path.dirname(__file__))
      
      # 获取user_data路径
      USER_DATA_PATH = os.path.join(BASE_PATH,'db','user_data')
      # print(USER_DATA_PATH)
      # D:\Users\ycc\PycharmProjects\ATM\db\user_data
      
      # 获取log路径
      LOG_PATH =os.path.join(BASE_PATH,'log')
      
      """
      logging配置
      """
      
      import os
      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_dir = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
      
      logfile_name = 'atm_log'  # log文件名
      
      # 如果不存在定义的日志目录就创建一个
      if not os.path.isdir(logfile_dir):
          os.mkdir(logfile_dir)
      
      # log文件的全路径
      logfile_path = os.path.join(LOG_PATH, logfile_name)
      
      # log配置字典
      LOGGING_DIC = {
          'version': 1,
          'disable_existing_loggers': False,
          'formatters': {
              'standard': {
                  'format': standard_format
              },
              'simple': {
                  'format': simple_format
              },
          },
          'filters': {},
          'handlers': {
              #打印到终端的日志
              'console': {
                  'level': 'DEBUG',
                  'class': 'logging.StreamHandler',  # 打印到屏幕
                  'formatter': 'simple'
              },
              #打印到文件的日志,收集info及以上的日志
              'default': {
                  'level': 'DEBUG',
                  'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                  'formatter': 'standard',
                  'filename': logfile_path,  # 日志文件
                  'maxBytes': 1024*1024*5,  # 日志大小 5M
                  'backupCount': 5,
                  'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
              },
          },
          'loggers': {
              #logging.getLogger(__name__)拿到的logger配置
              '': {
                  'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                  'level': 'DEBUG',
                  'propagate': True,  # 向上(更高level的logger)传递
              },
          },
      }
      
      
      def load_my_logging_cfg():
          logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
          logger = logging.getLogger(__name__)  # 生成一个log实例
          logger.info('It works!')  # 记录该文件的运行状态
      
      if __name__ == '__main__':
          load_my_logging_cfg()
          
      
          
      '''
      方式二:
      import logging
      logging.basicConfig(
          # 1.日志输出位置:1、终端 2、文件
          filename = 'access.log', # 不指定,默认打印到终端
      
          # 2.日志格式
          format='%(asctime)s - %(name)s - %(levlename)s - %(module)s: %(message)s',
      
          # 3.时间格式
          datefmt='%Y-%m-%d %H:%M:%S %p',
      
          # 4.日志级别
          # critical => 50
          # error => 40
          # warning => 30
          # info => 20
          # debug => 10
          level=10,
      )
      
      
      logging.debug('调式debug')
      logging.info('消息info')
      logging.warning('警告warn')
      logging.error('错误error')
      logging.critical('严重critical')
      '''