• Python之常用模块(二)


    shelve

    xml处理

    configparser

    hashlib

    logging

     

    shelve模块

    shelve是一个简单的k,v将内存数据通过文件持久化的模块,可以持久化任何pickle可支持的python数据格式

    import shelve

    sw = shelve.open('shelve_test.pkl') # 创建shelve对象

    name = ['13', '14', '145', 6] # 创建一个列表

    dist_test = {"k1":"v1", "k2":"v2"}

    sw['name'] = name # 将列表持久化保存

    sw['dist_test'] = dist_test

    sw.close() # 关闭文件,必须要有

    sr = shelve.open('shelve_test.pkl')

    print(sr['name']) # 读出列表

    print(sr['dist_test']) # 读出字典

    sr.close()

     

    xml处理模块

    xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。

    xml的格式如下,就是通过<>节点来区别数据结构的:

    <?xml version="1.0"?>

    <data>

    <country name="Liechtenstein">

    <rank updated="yes">2</rank>

    <year>2008</year>

    <gdppc>141100</gdppc>

    <neighbor name="Austria" direction="E"/>

    <neighbor name="Switzerland" direction="W"/>

    </country>

    <country name="Singapore">

    <rank updated="yes">5</rank>

    <year>2011</year>

    <gdppc>59900</gdppc>

    <neighbor name="Malaysia" direction="N"/>

    </country>

    <country name="Panama">

    <rank updated="yes">69</rank>

    <year>2011</year>

    <gdppc>13600</gdppc>

    <neighbor name="Costa Rica" direction="W"/>

    <neighbor name="Colombia" direction="E"/>

    </country>

    </data>

    xml协议在各个语言里的都 是支持的,在python中可以用以下模块操作xml

    import xml.etree.ElementTree as ET

    tree = ET.parse('test.xml') # 读取xml文件,并以Element对象的形式保存

    root = tree.getroot() # 获取根

    for child in root: # 遍历root下的子标签

    print(child.tag, child.attrib) # 打印标签名和属性

    for i in child:

    print(i.tag, i.text, i.attrib) # 打印标签名值和属性

    输出结果:

    country {'name': 'Liechtenstein'}

    rank 2 {'updated': 'yes'}

    year 2008 {}

    gdppc 141100 {}

    neighbor None {'direction': 'E', 'name': 'Austria'}

    neighbor None {'direction': 'W', 'name': 'Switzerland'}

    country {'name': 'Singapore'}

    rank 5 {'updated': 'yes'}

    year 2011 {}

    gdppc 59900 {}

    neighbor None {'direction': 'N', 'name': 'Malaysia'}

    country {'name': 'Panama'}

    rank 69 {'updated': 'yes'}

    year 2011 {}

    gdppc 13600 {}

    neighbor None {'direction': 'W', 'name': 'Costa Rica'}

    neighbor None {'direction': 'E', 'name': 'Colombia'}

    我们也可以通过标签名来获取某一类标签的内容

    for node in root.iter('year'): # 仅遍历标签名为year的标签

    print(node.tag, node.text, node.attrib)

    输出结果:

    year 2008 {}

    year 2011 {}

    year 2011 {}

    xml的常用操作

    修改:

    import xml.etree.ElementTree as ET

    tree = ET.parse('test.xml') # 读取xml文件,并以Element对象的形式保存

    root = tree.getroot() # 获取根

    for node in root.iter('year'): # 遍历year标签

    node.text = str(int(node.text) + 1) # 将year标签的值+1,注意,读出来的标签的值都是字符串形式,注意数据类型转换

    node.set('updated', 'yes') # 更新该标签

    tree.write('test_2.xml') # 将结果写到文件,可以写到源文件也可以写到新的文件中

    删除:

    import xml.etree.ElementTree as ET

    tree = ET.parse('test.xml') # 读取xml文件,并以Element对象的形式保存

    root = tree.getroot() # 获取根

    for country in root.findall('country'): # 遍历所有country标签

    rank = int(country.find('rank').text) # 在country标签查找名为rank的纸标签

    if rank > 50: # 判断如果rank标签的值大于50

    root.remove(country) # 删除该标签

    tree.write('test_3.xml')

    说明:

    iter方法用于查找的最终标签,也就是下面没子标签的标签,获取他的值和属性的

    findall方法用于查找还有子标签的子标签,然后和用fandall返回的对象的find方法获取找到的标签的子标签

    创建自己的xml文档

    import xml.etree.ElementTree as ET

    new_xml = ET.Element("namelist") # 新建根节点,或者说xml对象

    name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"}) # 给新xml对象创建子标签

    age = ET.SubElement(name,"age",attrib={"checked":"no"}) # name标签在创建子标签age,attrib变量为属性

    sex = ET.SubElement(name,"sex")

    sex.text = '33' # 给标签赋值

    name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})

    age = ET.SubElement(name2,"age")

    age.text = '19'

    et = ET.ElementTree(new_xml) #生成文档对象

    et.write("test.xml", encoding="utf-8",xml_declaration=True) # 将xml对象保存到文件xml_declaration表示xml文档的声明

    ET.dump(new_xml) #打印生成的格式

     

     

    ConfigParser模块

    ConfigParser模块是用来处理配置文件的包,配置文件的格式如下:中括号“[ ]”内包含的为section。section 下面为类似于key-value 的配置内容。常见很多服务的都是类似这种格式的,比如MySQL

    假设我们有这样一个配置文件

    [DEFAULT]
    name = www.qq.com
    [dbs]
    username = root
    passord = 123.com
    host = 127.0.0.1

    [server]
    name = www.baidu.com
    port = 80

    读取配置文件

    import configparser

    config = configparser.ConfigParser() # 创建configparser对象

    config.read('example.ini') # 读取配置件

    print(config.sections()) # 获取所有的session

    输出结果

    ['dbs', 'server']

    注意:

    可以看到这里没有输出DEFAULT,因为在Python中DEFAULT session有特殊用途,相当于所有session的默认值,也就是当DEFAULT中定义了一个key和value,此时session中这个不存在的时候,这个key的值就是DEFAULT定义的value

    例如

    print(config['dbs']['name'])

    输出结果就是

    www.qq.com

    说明:

    可以看到读取配置文件后的返回的对象有点类似于字典,可以通过key的方式将配置文件中的值一一取出来,甚至可以使用in关键字判断key是否存在

    print('server' in config)

    输出结果

    True

    其他常用操作

    读:

    print(config.options('dbs')) # 获取某个session下的所有option,也就是key

    输出结果

    ['username', 'passord', 'host', 'name']

    print(config.items('dbs')) # 获取某个session的键值列表,类似字典的items方法

    输出结果

    [('name', 'www.qq.com'), ('username', 'root'), ('passord', '123.com'), ('host', '127.0.0.1')]

    print(config.get('dbs', 'host')) # 获取某个session下的某个option的值

    输出结果

    127.0.0.1

    port = config.getint('server', 'port') # 获取某个session下的某个option的值,并以int的方式返回

    print(port)

    print(type(port))

    类似的方法还有getfloat和getboolean方法,当然前提是配置文件中的值就是对应的类型,否则会报错

    说明:

    配置文件中yes、True、1、true等为真,也就是通过getboolean返回的是True,no、False、0、false等为假,也就是返回的是False

    删除:

    config.remove_option('dbs','host') # 删除option

    config.remove_section('server') # 删除session

     

     

    hashlib模块

    用于加密相关的操作,3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法

    import hashlib

    m = hashlib.md5()

    m.update(b"Hello")

    m.update(b"It's me")

    print(m.digest())

    m.update(b"It's been a long time since last time we ...")

    print(m.digest()) #2进制格式hash

    print(len(m.hexdigest())) #16进制格式hash

    '''

    def digest(self, *args, **kwargs): # real signature unknown

    """ Return the digest value as a string of binary data. """

    pass

    def hexdigest(self, *args, **kwargs): # real signature unknown

    """ Return the digest value as a string of hexadecimal digits. """

    pass

    '''

    import hashlib

    # ######## md5 ########

    hash = hashlib.md5()

    hash.update('admin')

    print(hash.hexdigest())

    # ######## sha1 ########

    hash = hashlib.sha1()

    hash.update('admin')

    print(hash.hexdigest())

    # ######## sha256 ########

    hash = hashlib.sha256()

    hash.update('admin')

    print(hash.hexdigest())

    # ######## sha384 ########

    hash = hashlib.sha384()

    hash.update('admin')

    print(hash.hexdigest())

    # ######## sha512 ########

    hash = hashlib.sha512()

    hash.update('admin')

    print(hash.hexdigest())

     

     

    logging模块

    很多程序都有记录日志的需求,并且日志中包含的信息有正常的程序访问日志,还有可能有错误日志,警告信息输出,logging模块提供了标准的日志接口

    日志等级:

    CRITCAL = 50

    ERROR = 40

    WARING = 30

    INFO = 20

    DEBUG = 10

    设置记录日志等级,这个等级(数值)以下(小于这个数值)的日志将不会被记录。

    import logging

    logging.warning("user [alex] attempted wrong password more than 3 times")#日志等级及日志内容

    logging.critical("server is down")

    #输出

    WARNING:root:user [alex] attempted wrong password more than 3 times

    CRITICAL:root:server is down

     

    如果想把日志写到文件里,也很简单

    import logging

    logging.basicConfig(filename='example.log',level=logging.INFO)

    logging.debug('This message should go to the log file')

    logging.info('So should this')

    logging.warning('And this, too')

    其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。

    logging.basicConfig(filename='example.log',level=logging.INFO)

    感觉上面的日志格式忘记加上时间啦,日志不知道时间怎么行呢,下面就来加上!

    import logging

    logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')

    logging.warning('is when this event was logged.')

    #输出

    12/12/2010 11:46:36 AM is when this event was logged.

     

     

    如果想同时把log打印在屏幕和文件日志里

    import logging

    #create logger

    logger = logging.getLogger('TEST-LOG')

    logger.setLevel(logging.DEBUG)

    # create console handler and set level to debug

    ch = logging.StreamHandler()

    ch.setLevel(logging.DEBUG)

    # create file handler and set level to warning

    fh = logging.FileHandler("access.log")

    fh.setLevel(logging.WARNING)

    # create formatter

    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')

    # add formatter to ch and fh

    ch.setFormatter(formatter)

    fh.setFormatter(formatter)

    # add ch and fh to logger

    logger.addHandler(ch)

    logger.addHandler(fh)

    # 'application' code

    logger.debug('debug message')

    logger.info('info message')

    logger.warn('warn message')

    logger.error('error message')

    logger.critical('critical message')

  • 相关阅读:
    关于加密程序
    C++11的新特性lambda的小试牛刀RAII
    自动生成makefile的脚本
    关于pcre正则表达式库libpcre
    利用PHP执行SQL文件,将SQL文件导入到数据库
    Linux 系统是否适合于您?
    一个少年电脑病毒作者的独白
    PHP编程效率的20个要点
    JVM源码分析之javaagent原理完全解读
    如何更好的利用Node.js的性能极限
  • 原文地址:https://www.cnblogs.com/binges/p/5247750.html
Copyright © 2020-2023  润新知