• 常用内置模块(二)--logging、hashlib、shelve、xml、configparser


    一、logging模块

    1、logging作用

       1. 控制日志级别
       2. 控制日志格式
       3. 控制输出的目标为文件

    2、日志级别

    1 logging.debug('debug日志') # 10
    2 logging.info('info日志') # 20
    3 logging.warning('warning日志') #30
    4 logging.error('error日志')#40
    5 logging.critical('critical日志') #50

    3、示例

    import logging
    
    # 1. logger对象: 负责生产各种级别的日志
    logger1 = logging.getLogger('用户交易')  # 日志名用来标识日志的与什么业务有关
    
    # 2. filter对象: 过滤日志(很少使用)
    
    # 3. handler对象: 控制日志输出目标位置,以及编码标准
    fh1 = logging.FileHandler('a1.log',encoding='utf-8')
    fh2 = logging.FileHandler('a2.log',encoding='utf-8')
    ch = logging.StreamHandler()
    
    # 4. formmater对象:控制日志的格式
    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 - %(levelname)s :  %(message)s',
        datefmt='%Y-%m-%d %H:%M:%S %p'
    )
    
    # 5. 绑定logger对象与handler对象
    logger1.addHandler(fh1)
    logger1.addHandler(fh2)
    logger1.addHandler(ch)
    
    # 6. 绑定handler对象与formatter对象
    
    fh1.setFormatter(formatter1)
    fh2.setFormatter(formatter1)
    ch.setFormatter(formatter2)
    
    # 7. 设置日志级别,有logger对象与handler对象两层关卡,必须都放行最终日志才会放行,通常二者级别相同
    logger1.setLevel(10)
    fh1.setLevel(10)
    fh2.setLevel(10)
    ch.setLevel(10)
    
    # 8. 使用logger对象产生日志
    logger1.info('ffffffff')

    4、log配置字典

    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            'ch': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到终端
                'formatter': 'simple'
            },
            #打印到a1.log文件的日志
            'fh1': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': fh1_path,  # 日志文件的路径
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
            # 打印到a2.log文件的日志
            'fh2': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'formatter': 'simple',
                'filename': fh2_path,  # 日志文件的路径
                'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            },
    
        },
        'loggers': {
            '': {
                'handlers': ['fh1', 'fh2', 'ch'],
                'level': 'DEBUG',
            },
        },
    }
    logging.config.dictConfig(settings.LOGGING_DIC)
    
    logger1=logging.getLogger('用户交易')
    #logger1-> fh1,fh2,ch
    logger1.info('复古风刚刚兴起')
    
    logger2=logging.getLogger('用户权限')
    #logger2-> fh1,fh2,ch
    logger2.error('TOm没有执行权限')
    调用log配置字典

    二、hashlib模块

    十 hashlib模块
    # 1、什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, 
    SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值
    # 2、hash值的特点是: #2.1 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验 #2.2 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码 #2.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的

     hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()为工厂运送原材料),经过加工返回的产品就是hash值

    import hashlib
    
    # 方法一、
    # 1. 造出一个hash工厂
    m = hashlib.md5()   #=hashlib.sha256()
    
    # 2. 给工厂运送原材料
    m.update('hello_baby'.encode('utf-8'))   # 必须是bytes类型
    m.update('love_you'.encode('utf-8'))
    
    # 3. 产出产品
    print(m.hexdigest())    # 43a09074cc658f190d053f223dcb4497
    
    
    # 方法二、
    # 1. 造出一个hash工厂
    m = hashlib.md5('hello_baby'.encode('utf-8'))
    
    # 2. 给工厂运送原材料
    m.update('love_you'.encode('utf-8'))
    
    # 3. 产出产品
    print(m.hexdigest())    # 43a09074cc658f190d053f223dcb4497
    # 一、文件校验
    m = hashlib.md5()
    
    with open('test.txt','rb') as f:
        for line in f:
            m.update(line)
    
    print(m.hexdigest())
    
    
    # 二、密码加密
    password = input('>>:').strip()
    
    m = hashlib.md5()
    m.update(password.encode('utf-8'))
    print(m.hexdigest())
    
    # 密码加盐处理思想,可以在用户输入的密码中加入其他的字符,例如:
    password = input('>>:').strip()
    m = hashlib.md5()
    m.update('天王盖地虎'.encode('utf-8'))   # 进行加盐处理
    m.update(password.encode('utf-8'))
    print(m.hexdigest())
    实际应用
    # hmac 模块,用于强制性的加盐处理
     
    import hmac
     
    m = hmac.new('宝塔镇河妖'.encode('utf-8'))   # new(必须要传入位置参数)
    m.update('abc154728'.encode('utf-8'))
     
    print(m.hexdigest())

    三、shelve模块

     shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型

    1、shelve模块也是一种序列化模块,内部使用的是pickle模块,所以也存在跨平台性差的问题

    2、特点:

       只要提供一个文件名即可

       读写的方式和字典一样

       将数据以类似字典的形式在文件中读写

    3、应用场景

      在单击的程序中使用

    4、使用方法

    (1)序列化

    1 import shelve
    2 
    3 s1= shelve.open('a.txt')      # 打开文件
    4 s1['week']=["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"]
    5 s1['person']={"name": "Zero", "age": 8, "height": 180}     # 写操作
    6 s1.close()     # 关闭文件

    (2)反序列化

    import shelve
    
    s2 = shelve.open('a.txt')     # 打开文件
    print(s2.get('week'))
    print(s2.get('person'))
    print(s2.get('person')['age'])    # 读取文件中内容
    s2.close()        # 关闭文件

    四、xml模块

    1、XML全称:可扩展标记语言,标记指的是代表某种含义的字符 XML<>

    2、为什么要用xml 

     (1)为能够在不同的平台间继续数据的交换
     (2)为了使交换的数据能让对方看懂,就需要按照一定的语法规范来书写

    3、语法格式

    (1)任何的起始标签都必须有一个结束标签。
      <tagname></tagname>
      <tagname></tagname>
      <tagname/> 简化写法

    (2)可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/)。

        例如<ABC/>:XML解析器会将其翻译成<ABC></ABC>。
    (3)标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。

    (4)所有的特性都必须有值(特性指的是属性)。

    1 <person name="aaa">
    2 </person>

    (5)所有的特性都必须在值的周围加上双引号。

    4、注意点

    (1)最外层有且只有一个标签,这个标签为根标签
    (2)第一行应该有文档声明,用于高速计算机怎么理解
      例如:<?xml version="1.0" encoding="utf-8"?>

    1 <person>
    2     <sut1>
    3     </stu1>
    4     <sut2>
    5     </stu2>
    6 </person>
    标签嵌套

    5、使用场景:

    (1)配置文件
    (2)常规的数据交换。 例如从服务器获取一段新闻

    6、方法及属性

    (1).ElementTree 表示整个文件的元素树
    (2.)Element 表示一个节点
     a.属性
         text      开始标签和结束标签中间的文本
         attrib    所有的属性     字典类型
         tag       标签的名字
     b.方法
        get 获取某个属性的值
    import xml.etree.ElementTree as et
    
    # 读取xml文档到内存中  得到一个包含所有数据的节点树
    # 每一个标签就称之为一个节点 或 元素
    tree = et.parse("text.xml")
    
    # 获取根标签
    root = tree.getroot()
    
    # 获取所有的country   
    print(root.find("country"))   # 找的是第一个
    print(root.findall("country"))   # 找的是所有
    
    # 获取字标签
    print(root.iter("country"))
    for i in root.iter("country"):
        print(i)
    
    # 遍历整个xml
    for country in root:
         print(country.tag,country.attrib,country.text)
            for t in country:
                  print(t.tag, t.attrib, t.text)
    
    print(root.find("country").get("name"))    
    遍历

    7、增删改查

    1.解析XML
        查找标签
        find      在子标签中获取名字匹配第一个
        findall   在子标签中获取名字匹配的所有标签
        iter(tagname)      在全文中查找[匹配的所有标签 返回一个迭代器
    
    2.生成XML
        用ElmentTree
        parse()  解析一个文件
        getroot() 获取根标签
        write()  写入到文件
    
    3.修改xml
        set 一个属性
        remove 一个标签
        append 一个标签
    1 # 读取到内存
     2 tree = et.parse("text.xml")
     3 for country in tree.findall("country"):
     4      yeartag = country.find("year")
     5      yeartag.text = str(int(yeartag.text) + 1)   修改标签文本
     6 
     7      country.remove(country.find("year"))     删除标签
     8 
     9     # 添加子标签
    10     newtag = et.Element("newTag")
    11     # 文本
    12     newtag.text = "123"
    13     #属性
    14     newtag.attrib["name"] = "DSB"
    15     #添加
    16     country.append(newtag)
    17 
    18 # 写回到内存
    19 tree.write("text.xml",encoding="utf-8",xml_declaration=False)
    增删改查

    8、生成xml文档

    1 import xml.etree.ElementTree as et
     2 # 创建根标签
     3 root = et.Element("root")
     4 # 创建节点树
     5 t1 = et.ElementTree(root)
     6 
     7 # 加一个peron标签
     8 persson = et.Element("person")
     9 persson.attrib["name"] = "yyh"
    10 persson.attrib["sex"] = "man"
    11 persson.attrib["age"] = "20"
    12 persson.text = "这是一个person标签"
    13 
    14 root.append(persson)
    15 
    16 # 写入文件
    17 t1.write("newXML.xml",encoding="utf-8",xml_declaration=True)
    生成

     五、configparser模块

    ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section), 每个节可以有多个参数(键=值)。使用的配置文件的好处就是不用在程序员写死,可以使程序更灵活。 

    注意:在python 3 中ConfigParser模块名已更名为configparser

    configparser函数常用方法:

    读取配置文件:

     1 read(filename) #读取配置文件,直接读取ini文件内容
     2 
     3 sections() #获取ini文件内所有的section,以列表形式返回['logging', 'mysql']
     4 
     5 options(sections) #获取指定sections下所有options ,以列表形式返回['host', 'port', 'user', 'password']
     6 
     7 items(sections) #获取指定section下所有的键值对,[('host', '127.0.0.1'), ('port', '3306'), ('user', 'root'), ('password', '123456')]
     8 
     9 get(section, option) #获取section中option的值,返回为string类型
    10 >>>>>获取指定的section下的option <class 'str'> 127.0.0.1
    11 
    12 getint(section,option) 返回int类型
    13 getfloat(section, option)  返回float类型
    14 getboolean(section,option) 返回boolen类型

    举例如下:

    配置文件ini如下:

    [logging]
    level = 20
    path =
    server =
    
    [mysql]
    host=127.0.0.1
    port=3306
    user=root
    password=123456

    注意,也可以使用:替换=

    代码如下:

    import configparser
    from until.file_system import get_init_path
    
    conf = configparser.ConfigParser()
    file_path = get_init_path()
    print('file_path :',file_path)
    conf.read(file_path)
    
    sections = conf.sections()
    print('获取配置文件所有的section', sections)
    
    options = conf.options('mysql')
    print('获取指定section下所有option', options)
    
    
    items = conf.items('mysql')
    print('获取指定section下所有的键值对', items)
    
    
    value = conf.get('mysql', 'host')
    print('获取指定的section下的option', type(value), value)

    运行结果如下:

    file_path : /Users/xxx/Desktop/xxx/xxx/xxx.ini
    获取配置文件所有的section ['logging', 'mysql']
    获取指定section下所有option ['host', 'port', 'user', 'password']
    获取指定section下所有的键值对 [('host', '127.0.0.1'), ('port', '3306'), ('user', 'root'), ('password', '123456')]
    获取指定的section下的option <class 'str'> 127.0.0.1

    综合使用方法:

    import configparser
    """
    读取配置文件信息
    """
    
    class ConfigParser():
    
        config_dic = {}
        @classmethod
        def get_config(cls, sector, item):
            value = None
            try:
                value = cls.config_dic[sector][item]
            except KeyError:
                cf = configparser.ConfigParser()
                cf.read('settings.ini', encoding='utf8')  #注意setting.ini配置文件的路径
                value = cf.get(sector, item)
                cls.config_dic = value
            finally:
                return value
    
    
    if __name__ == '__main__':
        con = ConfigParser()
        res = con.get_config('logging', 'level')
        print(res
  • 相关阅读:
    多进程多线程
    JS---闭包
    Canvas:时钟
    CANVAS画布与SVG的区别
    CSS盒模型
    CSS---伪类与伪元素的区别
    CSS生成内容
    利用画布绘制折线图
    uiwebview与objective-c
    GoBelieve JS IM SDK接入备忘
  • 原文地址:https://www.cnblogs.com/zhangbingsheng/p/10398448.html
Copyright © 2020-2023  润新知