• logging模块、sys模块、shelve模块


    一.logging模块

    1.logging模块就是用于记录日志的,日志就是记录某个时间点,发生的事情。

    2.记录日志是为了日后来复查,提取有用的信息。

    3.如何去记录日志:可以直接打开文件,记录信息,但是会出现两个问题:1.记录的数据格式不通用,只能自己识别;2.解析数据麻烦。所以我们需要一个简单的方法,logging模块就是这样的一种方法。

    4.日志的级别,从低到高为:

    1.debug   10    调试信息(用于记录程序在开发过程中的调试记录)

    2.info        20    记录普通信息 (记录简单的信息)

    3.warning  30    警告信息 (当某些操作可能发生错误时,就记录为警告信息)

    4.error       40    错误信息 (当程序遇到错误时)

    5.critical     50    严重信息 (当程序遇到问题无法继续执行时)

    随着时间的推移,日志会越来越多,查看信息就比较麻烦,所以我们需要把日志进行分级,方便查找。

    默认情况下级别为warning,输出的位置是控制台,默认的日志格式为:  级别:日志生成器的名称:信息

    如何修改默认的参数:

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

    如果我们需要更加详细的去定制logging的各项功能,需要以下操作:

    四种核心角色:

    1.Logger    日志生成器   负责产生一条完整的日志

    2.Filter       过滤器          负责对日志进行过滤

    3.Handler   处理器          负责将日志输出到指定位置

    4.Formater 格式化          负责处理日志显示的格式

    可在logging.basicConfig()函数中通过具体参数来更改logging模块默认行为,可用参数有
    filename:用指定的文件名创建FiledHandler(后边会具体讲解handler的概念),这样日志会被存储在指定的文件中。
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    format:指定handler使用的日志显示格式。 
    datefmt:指定日期时间格式。 
    level:设置rootlogger(后边会讲解具体概念)的日志级别 
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件,默认为sys.stderr。若同时列出了filename和stream两个参数,则stream参数会被忽略。
    
    
    
    #格式
    %(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:用户输出的消息
    #自定义四种核心角色  完成日志的输出
    # 参数指定的是生成器的名称   (因为可以同时存在多个生成器)
    mylog = logging.getLogger("mylog")
    # 设置生成器的级别  低于该级别的不会生成
    mylog.setLevel(10)
    #
    # 过滤器 这里不讲! 需要使用面向对象的基础知识点! (不常用)
    #
    # 处理器
    handler = logging.FileHandler("youlog.txt",encoding="utf8",)
    # 将处理器绑定给生成器, add函数表明了  一个生成器可以添加多个处理器
    mylog.addHandler(handler)
    
    
    # 格式化处理器
    formater = logging.Formatter(fmt="%(filename)s %(levelname)s %(asctime)s %(message)s")
    # 将格式化处理器 绑定给  handler
    handler.setFormatter(formater)
    
    mylog.info("info")
    四种核心角色
    #需求: 有一个登陆注册 功能 需要记录用户操作日志, 程序员需要看到最详细的信息,而boss只需要看到简单的操作信息
    
    #实现: 按照不同的格式输出到不同的文件中
    mylog = logging.getLogger("mylog")
    # 设置生成器的级别  低于该级别的不会生成
    mylog.setLevel(10)
    
    
    # 过滤器 这里不讲! 需要使用面向对象的基础知识点! (不常用)
    
    # 给程序员看的日志处理器
    handler1 = logging.FileHandler("youlog.txt",encoding="utf8",)
    #将处理器 绑定给生成器, add函数表明了  一个生成器可以添加多个处理器
    mylog.addHandler(handler1)
    
    
    # 给老板看的日志处理器
    handler2 = logging.FileHandler("boss.txt",encoding="utf8",)
    #将处理器 绑定给生成器, add函数表明了  一个生成器可以添加多个处理器
    mylog.addHandler(handler2)
    
    
    # 程序员的格式化处理器
    formater1= logging.Formatter(fmt="%(threadName)s %(funcName)s %(module)s %(filename)s %(levelname)s %(asctime)s %(message)s")
    # 将格式化处理器 绑定给  handler
    handler1.setFormatter(formater1)
    
    
    # 老板的格式化处理器
    formater2= logging.Formatter(fmt="%(levelname)s %(asctime)s %(message)s")
    # 将格式化处理器 绑定给  handler
    handler2.setFormatter(formater2)
    不同格式输出到不同地方

    一条日志的生命周期:

    1.由Logger产生日志

    2.交给过滤器进行过滤

    3.交给Handler按照Formater的格式进行输出

    以上三步都可以对日志进行筛选,也就是指定日志的等级

    以上操作固然能够实现自定义输出,但是每次写日志,都要写一次上面的代码,太麻烦,所以我们需要一种更加快速有效的方式解决问题,我们可以把配置信息,写入一个字典中,具体解决方法如下:

    #现在需求已经实现了,但是,每次用日志都要写这么一堆代码,最好,能把配置写死,直接复制已有的配置信息
    
    #logging_config.py
    
    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_path = "dictconfig.log"
    
    LOGGING_DIC = {
        'version': 1,
        # 是否禁用已存在的生成器  这个值保持为False
        'disable_existing_loggers': False,
        # 四个key不能随便写 是固定
        'formatters': {
            # standard 表示格式化处理器的名字  相当于变量名称 可以随便写
            'standard': {
                # format是固定的不能随便写
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            #console是处理器的名称 可以随便写
            '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',  # 日志文件的编码
            },
            "ATM":{
                'level': 'DEBUG',
                'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': "ATMlog.txt",  # 日志文件
                'maxBytes': 1024*1024*5,  # 日志大小 5M
                'backupCount': 5, #日志文件最大个数
                'encoding': 'utf-8',  # 日志文件的编码
            }
        },
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
            #aa是生成器的名称 可以随便写
            # 如果将key(生成器名称)设置为空 则意味着将它作为默认的是你生成器
            '': {
                'handlers': ['default', 'console'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递 日志的继承
            },
            "atm":{
                'handlers': ['ATM'],  # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕
                'level': 'DEBUG',
                'propagate': True,  # 向上(更高level的logger)传递 日志的继承
            }
        },
    
    }
    
    
    #logging模块.py
    
    logging.config 专门用于配置logging 模块
    import logging.config
    
    # 导入包含配置字典的模块
    import loggin_config
    
    # 通过一个字典来配置 logging模块
    logging.config.dictConfig(loggin_config.LOGGING_DIC)
    
    #通过名称 来获取一个生成器
    aaloger = logging.getLogger("aa")
    
    # 输出日志
    aaloger.info("测试信息!")
    
    
    # 当要获取的名称不存在时 会返回一个默认的生成器
    aaloger = logging.getLogger("aasadsadsa")
    
    print(aaloger.name)
    # 输出日志
    aaloger.warning("测试信息!")
    字典配置
    # 了解知识点
    
    # 自己来定义四种核心角色
    
    import logging
    mylog = logging.getLogger("father")
    mylog.setLevel(10)
    
    handler = logging.FileHandler("father.log")
    mylog.addHandler(handler)
    handler.setLevel(10)
    
    fmter = logging.Formatter(fmt="%(threadName)s %(funcName)s %(module)s %(filename)s %(levelname)s %(asctime)s %(message)s")
    handler.setFormatter(fmter)
    
    # 在获取一个生成器  同时指定该生成器的父生成器是father这个生成器
    sonlog = logging.getLogger("father.son")
    
    # 需求:子生成器 的输出位置与父生成器不同  格式相同
    sonhandler = logging.FileHandler("son.txt",encoding="utf8")
    sonlog.addHandler(sonhandler)
    
    
    
    sonfmt = logging.Formatter(fmt="%(threadName)s %(funcName)s %(module)s %(filename)s %(levelname)s %(asctime)s %(message)s")
    sonhandler.setFormatter(sonfmt)
    
    
    
    # 继承后子生成器 可以直接使用父生成器的配置
    
    # mylog.info("这是一条日志信息!")
    # sonlog.info("这是  son 输出的日志信息!")
    
    
    #子生成器 在生成一个日志时  会自动给父生成器也发一个
    
    # 取消传递效果
    sonlog.propagate = False
    
    sonlog.info("这是  son 输出的日志信息!")
    日志的继承

    二.shelve模块

    shelve模块是用于序列化的模块。

    shelve模块只有一个函数,就是open,它是用于打开一个文件,打开之后的操作方式与字典完全一致。应用场景是在写的程序时一个单机程序时,可以考虑用这个模块。

    shelve模块的特点:

    1.可以识别python所有的基本数据类型

    2.只能被python编程语言识别,块平台性差

    import shelve
    
    s = shelve.open("test.she")
    s["name"] = "爱跟"
    
    
    s = shelve.open("test.she")
    s["dic"] = {"age":20}
    
    s = shelve.open("test.she")
    print(s["dic"])
    
    #注:在win系统下,会产生三个文件,在linux系统下只会产生一个文件

    三.sys模块

    sys是system的缩写,表示的是python解释器的系统

    os(operation system),表示的是操作系统

    sys模块用于操作系统调用解释器时传入的参数

    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       返回操作系统平台名称
    import sys
    
    # 当你要开发一款基于CMD的程序时 就需要使用这个属性了   因为一些操作系统没有界面  只能通过CMD来使用
    print(sys.argv)
    
    # 用于退出解释器  0表示正常退出
    # 3.sys.exit(0)
    
    
    
    print(sys.version)
    
    print(sys.platform)
    
    # 需求 开发一个基于CMD的复制文件的工具
    # 第一个参数表示被执行的py文件   第二个作为源文件路径  第三个作为目标文件的路径
    #
    # source_path = 3.sys.argv[1]
    # target_path = 3.sys.argv[2]
    #
    # print(source_path)
    # print(target_path)
    #
    #
    # with open(source_path,"rb") as f:
    #     with open(target_path,"wb") as f1:
    #         while True:
    #             data = f.read(1024)
    #             if not data:
    #                 break
    #             f1.write(data)
    
    # sys 处理与python解释器相关的一些操作,常用的有两个
    # 添加环境变量  3.sys.path
    # 获取调用解释器参数 3.sys.argv
  • 相关阅读:
    在Ubuntu下使用命令删除目录
    Visual Studio添加lib到链接依赖项的几种方法
    svn回到某个历史版本的做法
    iOS菜鸟成长笔记(3)——斯坦福公开课学习(1)
    VS自定义开发向导中的vsdir文件的简单说明
    OpenGL编程逐步深入(十一)组合变换
    iOS菜鸟成长笔记(2)——网易彩票练习
    AngularJs轻松入门(九)与服务器交互
    AngularJs轻松入门(八)Cookies读写
    AngularJs轻松入门(七)多视图切换
  • 原文地址:https://www.cnblogs.com/wangke0917/p/10084652.html
Copyright © 2020-2023  润新知