zoukankan      html  css  js  c++  java
  • 20181207(sys,shelve,logging)

     

    一、logging模块

    logging专门用来记录日志

    日志的级别分为五级,可以用数字表示,从低到高分别为:

    import  logging
    logging.info('info')   #10
    logging.debug('debug')   #20
    logging.warning('warning')  #30
    logging.error('errot')  #40
    logging.critical('crtical')   #50
    输出结果:
    WARNING:root:warning
    ERROR:root:errot
    CRITICAL:root:crtical
           
    默认情况下,级别为warning(30),输出的结果是控制台,默认的格式为  

     

    1、debug #调试信息(用于记录程序在开发过程中的调试信息,例如不清楚这个变量的值,打印一下)

    2、info #记录普通信息

    3、warning #警告信息(当某些操作可能发生错误,就记录为警告信息,设计一些敏感操作)

    4、error #错误信息(当程序遇到错误,例如数据类型转换失败)

    5、critical #严重错误(当程序遇到问题,无法继续执行,例如用户删除核心组件)

     

    为什么分级:随着时间的推移,日志会越来越多,提取有用信息变得困难。划分等级,方便查找,可快速定位想要的日志。

     

    修改默认的等级划分

    logging.basicConfig(filename='mylog.txt', #指定的日志文件名
                       filemode='a',   #指定文件打开模式 ,通常为a
                       level=logging.DEBUG,  #指定级别
                       format='%(filename)s %(levelname)s %(asctime)s %(message)s'
                      )

    logging.info('info')
    logging.debug('debug')
    logging.warning('warning')
    logging.error('errot')
    logging.critical('crtical')
    输出结果为:
    新建了mylog.txt文件,内容为:
    test2.py INFO 2018-12-07 10:00:33,172 info
    test2.py DEBUG 2018-12-07 10:00:33,197 debug
    test2.py WARNING 2018-12-07 10:00:33,197 warning
    test2.py ERROR 2018-12-07 10:00:33,197 errot
    test2.py CRITICAL 2018-12-07 10:00:33,198 crtical

     

    可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有:
    filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。不指定默认显示在屏幕上(不保存)
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”。还可指定为“w”(一般不用w)。
    format:指定handler使用的日志显示格式。
    datefmt:指定日期时间格式。
    level:设置rootlogger的日志级别  
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。


    format格式
    %(name)s:Logger的名字,并非用户名,详细查看

    %(levelno)s:数字形式的日志级别

    %(levelname)s:文本形式的日志级别

    %(pathname)s:调用日志输出函数的模块的完整路径名,可能没有

    %(filename)s:调用日志输出函数的模块的文件名

    %(module)s:调用日志输出函数的模块名

    %(funcName)s:调用日志输出函数的函数名

    %(lineno)d:调用日志输出函数的语句所在的代码行

    %(created)f:当前时间,用UNIX标准的表示时间的浮 点数表示

    %(relativeCreated)d:输出日志信息时的,自Logger创建以 来的毫秒数

    %(asctime)s:字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒

    %(thread)d:线程ID。可能没有

    %(threadName)s:线程名。可能没有

    %(process)d:进程ID。可能没有

    %(message)s:用户输出的消息

     

    四种核心角色:

    1、日志生成器logger 负责产生一条完整的日志

    2、过滤器filter 负责对日志进行过滤(不常用)

    3、处理器handler 负责将日志输出到指定位置(文件or终端)

    4、格式化formater 负责处理日志显示的格式

     

    日志的流程,三步走:

    由logger产生日志---》过滤器进行过滤---》交给handler按照formater的格式进行输出

     

    理解即可:
    import logging

    # logger:负责产生日志
    logger1 = logging.getLogger('xxx')

    # filter:过滤日志(不常用)

    #handler:控制日志打印到文件or终端
    fh1=logging.FileHandler(filename='a1.log',encoding='utf-8')
    fh2=logging.FileHandler(filename='a2.log',encoding='utf-8')
    sh=logging.StreamHandler()  #打印到终端,即显示在屏幕上

    # formatter:控制日志的格式
    formatter1=logging.Formatter(
    fmt='%(asctime)s - %(name)s - %(levelname)s - %(module)s: %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p'
    )

    formatter2=logging.Formatter(fmt='%(asctime)s - %(message)s')

    # 建立关系
    logger1.addHandler(fh1)
    logger1.addHandler(fh2)
    logger1.addHandler(sh)

    # 为handler对象绑定日志格式

    fh1.setFormatter(formatter1)
    fh1.setFormatter(formatter1)
    sh.setFormatter(formatter2)

    # 日志级别:注意两层关卡,必须都通过,日志才能正常记录
    logger1.setLevel(10)
    fh1.setLevel(10)
    fh2.setLevel(10)
    sh.setLevel(10)

    logger1.debug('调试信息')

    输出结果为:
    2018-12-09 13:12:17,618 - 调试信息
    同时生成两份文件。

     

    下面的这个例子常用。

    """
    logging配置
    """

    import os
    import logging.config
    import logging

    # 定义三种日志输出格式 开始

    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'

    # 定义日志的文件路径
    LOG_PATH = r'aa.log'

    # log配置字典
    LOGGING_DIC = {
       'version': 1,   #版本号,自定义即可
       'disable_existing_loggers': False,  #不用管
       
       # 定义日志的格式
       'formatters': {
           'standard': {
               'format': standard_format  #对应上面的定义格式
          },
           'simple': {
               'format': simple_format  #对应上面的定义格式
          },
    #       "id_simple":{   #此处的key自定义,具有标识和描述性即可
    #         'format'(此处key不能动,统一用format):id_simple_format(上面定义好的格式名)   #在上面自定义好后,在此处补充
    #       }
      },
       'filters': {},   #过滤器很少用,直接设置为空
       
       # 定义日志输出的目标:文件或者终端
       'handlers': {
           #打印到终端的日志
           'stream': {
               'level': 'DEBUG',  # 指定日志级别,注意大小写
               'class': 'logging.StreamHandler',  # 打印到屏幕
               'formatter': 'simple'  # 日志格式里面的key
          },
           #打印到文件的日志,收集info及以上的日志
           'default': {
               'level': 'DEBUG',   #日志级别
               'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
               'formatter': 'standard',  #上面的日志格式
               'filename': LOG_PATH,  # 日志文件
               'maxBytes': 1024*1024*5,  # 日志大小 5M,达到5M时会另存为其他文件(相当于把日志切分)
               'backupCount': 5,  #上面的日志最多保存五份
               'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
          },
      },
       'loggers': {
           #logging.getLogger(__name__)拿到的logger配置
           '': {  # 此处key为空就代表默认配置
               'handlers': ['default', 'stream'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
               'level': 'DEBUG',  #日志级别
               'propagate': False,  # 向上(更高level的logger)传递,通常为False
          },
      },
    }


    logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
    logger = logging.getLogger('egon')  # (拿到egon这条日志的配置) # 生成一个log实例
    logger.debug('It works!')    
       
    上述文件即可运行。  
       
    def load_my_logging_cfg(name):  #设置一个参数
       logging.config.dictConfig(LOGGING_DIC)  # 导入上面定义的logging配置
       logger = logging.getLogger(name)(拿到参数name这条日志的配置)   # 生成一个log实例
       logger.info('It works!')  # 记录该文件的运行状态,能否输出取决于字典中loggers和handlers的日志级别,还有其本身定义的日志级别。

     

     

     

    二、shelve

    shelve模块只有一个函数,就是用open打开一个文件,底层调用的是pickle模块,所以shelve模块支持所有的python数据类型,且无法跨平台。

    打开以后,操作方式与字典完全一致,可以当成字典处理,序列化内容。

    最常用的还是json。

    序列化数据并储存:
    import  shelve
    info1={'age':'18','height':'180','weight':'70'}
    info2={'age':'22','height':'170','weight':'60'}

    d=shelve.open('db.shv') #文件名没有则创建新文件
    d['egon']=info1
    d['alex']=info2
    d.close()   #记得关闭文件
    会在当前执行文件目录下生成三个文件:db.shv.bakdb.shv.datdb.shv.dir


    反序列化并读取:
    d=shelve.open('db.shv')  #无论是存还是取,第一步都是打开文件,最后一步关闭文件。
    print(d['egon'])
    print(d['alex'])
    d.close()
    输出结果为:
    {'age': '18', 'height': '180', 'weight': '70'}
    {'age': '22', 'height': '170', 'weight': '60'}


    修改数据:
    d=shelve.open('db.shv',writeback=True)   #修改时要加上writeback=True,否则无效。
    d['egon']['age']=33
    print(d['egon'])
    d.close()
    结果:
    {'age': 33, 'height': '180', 'weight': '70'}

     

    三、sys

    全称system,表示系统,指的是python解释器。(os指的是操作系统。)

    用于接受操作系统调用解释器时传入的参数。

    1 sys.argv           命令行参数List,第一个元素是程序本身路径
    2 sys.exit(n)        退出程序,正常退出时exit(0)
    3 sys.version        获取Python解释程序的版本信息
    4 sys.maxint         最大的Int值
    5 sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
    6 sys.platform       返回操作系统平台名称

    会用sys.path和sys.argv就行。

     

     

     

     

     

     

  • 相关阅读:
    通过加载Xib文件来创建UITableViewCell造成复用数据混乱问题方案
    iOS开发过程中常见错误问题及解决方案
    iOS开发常用第三方库
    KVC和KVO的理解(底层实现原理)
    iOS面试必备-iOS基础知识
    iOS应用适配IPV6
    Runtime运行时的那点事儿
    iOS应用性能调优的25个建议和技巧
    iOS清除缓存功能开发
    微信浏览器跳转页面后再返回,如何恢复到跳转前的位置的问题。
  • 原文地址:https://www.cnblogs.com/realadmin/p/10091450.html
Copyright © 2011-2022 走看看