zoukankan      html  css  js  c++  java
  • day 26 (configparser + logging + collections) 模块

    configparser模块

    该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)。

    创建文件

    来看一个好多软件的常见文档格式如下:

    复制代码
    [DEFAULT]    #  全局的组(组长) ,  下面的属性也是全局属性
    ServerAliveInterval = 45
    Compression = yes
    CompressionLevel = 9
    ForwardX11 = yes
      
    [bitbucket.org]    自定义的组名
    User = hg        自定义的option
      
    [topsecret.server.com]    自定义组名
    Port = 50022
    ForwardX11 = no
    复制代码

    如果想用python生成一个这样的文档怎么做呢?

    复制代码import configparser    #首先导入configparser模块  
    config = configparser.ConfigParser()  #实例化一个对象
    
    config["DEFAULT"] = {'ServerAliveInterval': '45',    #根据创建的对象来设置组名和option。
    'Compression': 'yes',          DEFAULT,在配置文件中有关键词的作用。(生命全局) 'CompressionLevel': '9', 'ForwardX11':'yes' } config['bitbucket.org'] = {'User':'hg'} config['topsecret.server.com'] = {'Host Port':'50022','ForwardX11':'no'} with open('example.ini', 'w') as configfile:    最后一步打开文件,写入文件。否则不会生效 config.write(configfile)
    复制代码

    查找文件

    复制代码
    import configparser
    
    config = configparser.ConfigParser()
    
    #---------------------------查找文件内容,基于字典的形式
    
    print(config.sections())        #  []    #得到了一个空列表,因为没有读取文件
    
    config.read('example.ini')
    
    print(config.sections())        #   ['bitbucket.org', 'topsecret.server.com']  #这一次读取了文件,所以打印出所有的组名
    
    print('bytebong.com' in config) # False    #判断组名是否在config这个对象中
    print('bitbucket.org' in config) # True
    
    
    print(config['bitbucket.org']["user"])  # hg    #打印相应组名中的option的值
    
    print(config['DEFAULT']['Compression']) #yes
    
    print(config['topsecret.server.com']['ForwardX11'])  #no
    
    
    print(config['bitbucket.org'])          #<Section: bitbucket.org>   #说明每一个组名是一个可迭代对象
    
    for key in config['bitbucket.org']:     # 注意,有default会默认default的键  #除了自身的optinon还会有全局的option
        print(key)
    
    print(config.options('bitbucket.org'))  # 同for循环,找到'bitbucket.org'下所有键
    
    print(config.items('bitbucket.org'))    #找到'bitbucket.org'下所有键值对
    
    print(config.get('bitbucket.org','compression')) # yes       get方法Section下的key对应的value
    复制代码

    增删改操作

    复制代码
    import configparser
    
    config = configparser.ConfigParser()
    
    config.read('example.ini')
    
    config.add_section('yuan')    在添加组名前,必须读取文件
    
    
    
    config.remove_section('bitbucket.org')    删除组名
    config.remove_option('topsecret.server.com',"forwardx11")    删除组名对应的 option
    
    
    config.set('topsecret.server.com','k1','11111')    找到对应组的option ,有则改之,无则添加
    config.set('yuan','k2','22222')
    
    config.write(open('new2.ini', "w"))    想要生效,必须写入文件

     

    logging模块

    logging 不会帮你自动添加日志的内容

    函数式简单配置

    import logging  
    logging.basicConfig(level = logging.DEBUG)    #加这一行的话默认全部打印,不加会默认从warning模式开始打印 logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')

    默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志,这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG),默认的日志格式为日志级别:Logger名称:用户输出消息。

    灵活配置日志级别,日志格式,输出位置:

    复制代码
    import logging  
    logging.basicConfig(level=logging.DEBUG,  
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',  
                        datefmt='%a, %d %b %Y %H:%M:%S',  
                        filename='/tmp/test.log',  
                        filemode='w')  
      
    logging.debug('debug message')  
    logging.info('info message')  
    logging.warning('warning message')  
    logging.error('error message')  
    logging.critical('critical message')
    复制代码

    编码格式不能设置

    不能同时输出到文件和屏幕

    配置参数:

    复制代码
    logging.basicConfig()函数中可通过具体参数来更改logging模块默认行为,可用参数有:
    
    filename:用指定的文件名创建FiledHandler,这样日志会被存储在指定的文件中。
    filemode:文件打开方式,在指定了filename时使用这个参数,默认值为“a”还可指定为“w”。
    format:指定handler使用的日志显示格式。
    datefmt:指定日期时间格式。
    level:设置rootlogger(后边会讲解具体概念)的日志级别
    stream:用指定的stream创建StreamHandler。可以指定输出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默认为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用户输出的消息
    复制代码

    logger对象配置

    复制代码
    import logging
    
    logger = logging.getLogger()
    # 创建一个handler,用于写入日志文件
    fh = logging.FileHandler('test.log',encoding='utf-8') 

    # 再创建一个handler,用于输出到控制台
    ch = logging.StreamHandler()
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setLevel(logging.DEBUG)

    fh.setFormatter(formatter)
    ch.setFormatter(formatter)
    logger.addHandler(fh) #logger对象可以添加多个fh和ch对象 
    logger.addHandler(ch)

    logger.debug('logger debug message')
    logger.info('logger info message')
    logger.warning('logger warning message')
    logger.error('logger error message')
    logger.critical('logger critical message')
    复制代码

    logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口,Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过:logger.setLevel(logging.Debug)设置级别,当然,也可以通过

    fh.setLevel(logging.Debug)单对文件流设置某个级别。

     简单配置
    import logging
    # 默认情况下 只显示 警告 及警告级别以上信息
    # logging.basicConfig(level=logging.DEBUG,
    # format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
    # datefmt='%a, %d %b %y %H:%M:%S',
    # filename = 'userinfo.log'
    # )
    # logging.debug('debug message') # debug 调试模式 级别最低
    # logging.info('info message') # info 显示正常信息
    # logging.warning('warning message') # warning 显示警告信息
    # logging.error('error message') # error 显示错误信息
    # logging.critical('critical message') # critical 显示严重错误信息

    # 编码格式不能设置
    # 不能同时输出到文件 和 屏幕

    # 配置logger对象
    import logging
    logger = logging.getLogger() # 实例化了一个logger对象

    fh = logging.FileHandler('test.log',encoding='utf-8') # 实例化了一个文件句柄
    sh = logging.StreamHandler()

    fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(fmt) # 格式和文件句柄或者屏幕句柄关联
    sh.setFormatter(fmt)
    sh.setLevel(logging.WARNING)

    # 吸星大法
    logger.addHandler(fh) # 和logger关联的只有句柄
    logger.addHandler(sh)
    logger.setLevel(logging.DEBUG)

    logger.debug('debug message') # debug 调试模式 级别最低
    logger.info('info message') # info 显示正常信息
    logger.warning('warning message') # warning 显示警告信息
    logger.error('error message') # error 显示错误信息
    logger.critical('critical message')


    # logging
    # logging 是记录日志的模块
    # 它不能自己打印内容 只能根据程序员写的代码来完成功能
    # logging模块提供5中日志级别,从低到高一次:debug info warning error critical
    # 默认从warning模式开始显示
    # 只显示一些基础信息,我们还可以对显示的格式做一些配置

    # 简单配置 配置格式 basicCondfig
    # 问题:编码问题,不能同时输出到文件和屏幕

    # logger对象配置
    # 高可定制化
    # 首先创造logger对象
    # 创造文件句柄 屏幕句柄
    # 创造格式
    # 使用文件句柄和屏幕句柄 绑定格式
    # logger对象和句柄关联
    # logger.setLevel
    # 使用的时候 logger.debug










    collections模块

    在内置数据类型(dict、list、set、tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter、deque、defaultdict、namedtuple和OrderedDict等。

    1.namedtuple: 生成可以使用名字来访问元素内容的tuple

    2.deque: 双端队列,可以快速的从另外一侧追加和推出对象

    3.Counter: 计数器,主要用来计数

    4.OrderedDict: 有序字典

    5.defaultdict: 带有默认值的字典

    namedtuple

    们知道tuple可以表示不变集合,例如,一个点的二维坐标就可以表示成:

    >>> p = (1, 2)

    但是,看到(1, 2),很难看出这个tuple是用来表示一个坐标的。

    这时,namedtuple就派上了用场:

    复制代码
    >>> from collections import namedtuple
    >>> Point = namedtuple('Point', ['x', 'y'])
    >>> p = Point(1, 2)
    >>> p.x
    1
    >>> p.y
    2
    复制代码

    似的,如果要用坐标和半径表示一个圆,也可以用namedtuple定义:

    #namedtuple('名称', [属性list]):
    Circle = namedtuple('Circle', ['x', 'y', 'r'])

    deque

    使用list存储数据时,按索引访问元素很快,但是插入和删除元素就很慢了,因为list是线性存储,数据量大的时候,插入和删除效率很低。

    deque是为了高效实现插入和删除操作的双向列表,适合用于队列和栈:

    >>> from collections import deque
    >>> q = deque(['a', 'b', 'c'])
    >>> q.append('x')
    >>> q.appendleft('y')
    >>> q
    deque(['y', 'a', 'b', 'c', 'x'])

    deque除了实现list的append()pop()外,还支持appendleft()popleft(),这样就可以非常高效地往头部添加或删除元素。

    OrderedDict

    使用dict时,Key是无序的。在对dict做迭代时,我们无法确定Key的顺序。

    如果要保持Key的顺序,可以用OrderedDict

    复制代码
    >>> from collections import OrderedDict
    >>> d = dict([('a', 1), ('b', 2), ('c', 3)])
    >>> d # dict的Key是无序的
    {'a': 1, 'c': 3, 'b': 2}
    >>> od = OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    >>> od # OrderedDict的Key是有序的
    OrderedDict([('a', 1), ('b', 2), ('c', 3)])
    复制代码

    意,OrderedDict的Key会按照插入的顺序排列,不是Key本身排序:

    >>> od = OrderedDict()
    >>> od['z'] = 1
    >>> od['y'] = 2
    >>> od['x'] = 3
    >>> od.keys() # 按照插入的Key的顺序返回
    ['z', 'y', 'x']

    defaultdict 

    有如下值集合 [11,22,33,44,55,66,77,88,99,90...],将所有大于 66 的值保存至字典的第一个key中,将小于 66 的值保存至第二个key的值中。

    即: {'k1': 大于66 'k2': 小于66}
    values = [11, 22, 33,44,55,66,77,88,99,90]
    
    my_dict = {}
    
    for value in  values:
        if value>66:
            if my_dict.has_key('k1'):
                my_dict['k1'].append(value)
            else:
                my_dict['k1'] = [value]
        else:
            if my_dict.has_key('k2'):
                my_dict['k2'].append(value)
            else:
                my_dict['k2'] = [value]
    原生字典解决方法
    from collections import defaultdict
    
    values = [11, 22, 33,44,55,66,77,88,99,90]
    
    my_dict = defaultdict(list)
    
    for value in  values:
        if value>66:
            my_dict['k1'].append(value)
        else:
            my_dict['k2'].append(value)
    defaultdict字典解决方法

    使dict时,如果引用的Key不存在,就会抛出KeyError。如果希望key不存在时,返回一个默认值,就可以用defaultdict

    >>> from collections import defaultdict
    >>> dd = defaultdict(lambda: 'N/A')
    >>> dd['key1'] = 'abc'
    >>> dd['key1'] # key1存在
    'abc'
    >>> dd['key2'] # key2不存在,返回默认值
    'N/A'
    例2

    Counter

    Counter类的目的是用来跟踪值出现的次数。它是一个无序的容器类型,以字典的键值对形式存储,其中元素作为key,其计数作为value。计数值可以是任意的Interger(包括0和负数)。Counter类和其他语言的bags或multisets很相似。

    c = Counter('abcdeabcdabcaba')
    print c
    输出:Counter({'a': 5, 'b': 4, 'c': 3, 'd': 2, 'e': 1})
    其他详细内容 http://www.cnblogs.com/Eva-J/articles/7291842.html














  • 相关阅读:
    新浪微盘又是一个给力的产品啊,
    InfoQ: 百度数据库架构演变与设计
    列式数据库——Sybase IQ
    MapR初体验 淘宝共享数据平台 tbdata.org
    IBM正式发布新一代zEnterprise大型机(组图) 大型机,IBM,BladeCenter,美国,纽约 TechWeb News
    1TB is equal to the number of how many GB? 1PB equal to is equal to the number of TB? 1EB PB? | PCfault.com
    Cassandra vs HBase | WhyNosql
    The Hadoop Community Effect
    雅虎剥离开源软件平台 Hadoop ,与风投新建 Hortonworks 公司 品味雅虎
    RowOriented Database 、ColumnOriented Database 、KeyValue Store Database 、DocumentOriented Database
  • 原文地址:https://www.cnblogs.com/zsdbk/p/8918899.html
Copyright © 2011-2022 走看看