zoukankan      html  css  js  c++  java
  • 模块(configparser+shutil+logging)

    一、configparser模块

    1、模块介绍

    configparser用于处理特定格式的文件,其本质上是利用open来操作文件。

    *注:(这里解释一下特定格式的文件)

    a、有section和option的格式,且section表现为列表形式,option表现为字典形式。

    # 注释1
    ;  注释2
     
    [section1] # 节点
    k1 = v1    #
    k2:v2       #
     
    [section2] # 节点
    k1 = v1    #
    
    指定格式
    特定格式说明

    举例:

    [tina]
    k2 = 34.5
    k1 = 11111
    
    [tony]
    "k2" = 'vi'
    "k1" = 've'
    
    [tom]
    "k2" = 'cw'
    "k1" = 'de'
    特定格式

    b、目前见过的只有Linux中的Samba配置文件

    2、模块常用功能

    (1)获取文件中的所有节点

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xx', encoding='utf-8')
    ret = config.sections()
    print(ret)
    
    #########以下是XX文件中的内容###########
    [tina]
    k2 = 34.5
    k1 = 11111
    
    [tony]
    "k2" = 'vi'
    "k1" = 've'
    
    [tom]
    "k2" = 'cw'
    "k1" = 'de'
    
    ############最后的执行结果############
    ['tina', 'tony', 'tom']
    获取xx文件中的所有节点

    (2)获取指定节点下的键值对

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xx', encoding='utf-8')
    ret = config.items('tina')
    print(ret)
    
    ######指定文件依然用上面例子中的,执行结果如下:#########
    [('k2', '34.5'), ('k1', '11111')]
    获取XX文件中指定节点tina下的键值对

    (3)获取指定节点下所有的键

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xx', encoding='utf-8')
    ret = config.options('tina')
    print(ret)
    获取XX文件下指定节点tina下所有的键

    (4)获取指定节点下指定key的值

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xx', encoding='utf-8')
     
     
    v = config.get('section1', 'k1')
    # v = config.getint('section1', 'k1')
    # v = config.getfloat('section1', 'k1')
    # v = config.getboolean('section1', 'k1')
     
    print(v)#根据值的数据类型不同,选择不同类型get,错误则报错
    只获取key对应的值

    (5)检查(判断)、删除、添加节点

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xx', encoding='utf-8')
     
     
    # 检查
    has_sec = config.has_section('section1')
    print(has_sec)
     
    # 添加节点
    config.add_section("tina")
    config.write(open('xx', 'w'))
     
    # 删除节点
    config.remove_section("tina")
    config.write(open('xx', 'w')
    对节点的检查、删除、添加操作

    (6)检查、删除、设置指定组内的键值对

    import configparser
     
    config = configparser.ConfigParser()
    config.read('xx', encoding='utf-8')
     
    # 检查
    has_opt = config.has_option('section1', 'k1')
    print(has_opt)
     
    # 删除
    config.remove_option('section1', 'k1')
    config.write(open('xx', 'w'))
     
    # 设置
    config.set('section1', 'k10', "123")
    config.write(open('xx', 'w'))
    对指定组内的键值对的操作

     二、shutil模块

    高级的文件、文件夹、压缩包处理(对压缩包的处理需要调用ZipFile 和 TarFile模块)的模块

    1、模块常用功能

     copyfile( src, dst)  从源src复制到dst中去。当然前提是目标地址是具备可写权限。抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉
     copymode( src, dst)  只是会复制其权限其他的东西是不会被复制的
     copystat( src, dst)  复制权限、最后访问时间、最后修改时间
     copy( src, dst)     复制一个文件到一个文件或一个目录
     copy2( src, dst)   在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,类似于cp –p的东西
     copy2( src, dst)   如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;如果是不在相同的文件系统的话就是做move操作
     copytree(olddir,newdir,True/Flase)  把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接

    展开说明:

    (1)shutil.copyfileobj(fsrc,fdst[,length])#将文件内容拷贝(覆盖)到另一个文件中

    import shutil
    shutil.copyfileobj(open('log.log','r'),open('db','w'))

    (2)shutil.copyfile(src,dst)#拷贝文件

    import shutil
    # shutil.copyfileobj(open('log.log','r'),open('db','w'))
    #执行结果是db中的文件内容被log文件中的内容覆盖掉了
    shutil.copyfile('db','db2')
    #执行结果是,新创建了一个db2文件,其内容和db中一样
    拷贝文件的栗子

    (3)shutil.copymode(src,dst)#仅拷贝权限。内容、组、用户均不变。

    shutil.copymode('文件1','文件2')#仅拷贝权限,内容、组、用户均不变。
    #############废话多一些更好理解,哈哈###############
    文件1和文件2中都有内容,shutil.copymode后文件1和文件2中的内容还为原来各自的内容,拷贝的仅仅是文件权限,在Linux中可能用的比较多。

     (4)shutil.copystat(src,dst)#拷贝状态的信息,包括:mode bits,atime,mtime,flags

    shutil.copystat('f1.log', 'f2.log')

    (5)shutil.copy(src,dst)#拷贝文件和权限

    import shutil
    shutil.copy('f1.log', 'f2.log')

    (6)shutil.copy2(src,dst)#拷贝文件和状态信息

    import shutil
    shutil.copy2('f1.log', 'f2.log')

    (7)shutil.ignore_patterns(*patterns)

    shutil.copytree(src,dst,symlinks=False,ignore=None)#递归的拷贝文件夹

    import shutil
    shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
    import shutil
    shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))

    (8)shutil.move(src,dst)#递归的去移动文件,类似mv命令,其实就是重命名

    import shutil 
    shutil.move('folder1', 'folder3')

    (9)shutil.make_archive(base_name,format,...)#创建压缩包并返回文件路径,例如:zip,tar

    base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
    如:feifei                        =>保存至当前路径
    如:/Users/tina/feifei =>保存至/Users/tina/
    format:	压缩包种类,“zip”, “tar”, “bztar”,“gztar”
    root_dir:	要压缩的文件夹路径(默认当前目录)
    owner:	用户,默认当前用户
    group:	组,默认当前组
    logger:	用于记录日志,通常是logging.Logger对象
    
    #将 /Users/tina/Downloads/test 下的文件打包放置当前程序目录
    import shutil
    ret = shutil.make_archive("feifei", 'gztar', root_dir='/Users/tina/Downloads/test')
      
      
    #将 /Users/tina/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录
    import shutil
    ret = shutil.make_archive("/Users/wupeiqi/feifei", 'gztar', root_dir='/Users/tina/Downloads/test')

     2、shutil模块与ZipFile 和 TarFile模块的关系

    shutil模块常常和ZipFile 和 TarFile这两个模块一起使用,用来对压缩包的处理

    import zipfile
    
    # 压缩
    z = zipfile.ZipFile('tina.zip', 'w')
    z.write('a.log')
    z.write('data.data')
    z.close()
    
    # 解压
    z = zipfile.ZipFile('tina.zip', 'r')
    z.extractall()
    z.close()
    
    zipfile解压缩
    import tarfile
    
    # 压缩
    tar = tarfile.open('your.tar','w')
    tar.add('/Users/tina/PycharmProjects/bbs2.log', arcname='bbs2.log')
    tar.add('/Users/tina/PycharmProjects/cmdb.log', arcname='cmdb.log')
    tar.close()
    
    # 解压
    tar = tarfile.open('your.tar','r')
    tar.extractall()  # 可设置解压地址
    tar.close()
    
    tarfile解压缩

    三、logging模块

    logging模块是用来记录日志且保证线程安全的模块。

    logging模块支持将日志信息保存到不同的目标域中,如:保存到日志文件中;以邮件的形式发送日志信息;以http get或post的方式提交日志到web服务器;以windows事件的形式记录等等。这些日志保存方式可以组合使用,每种方式可以设置自己的日志级别以及日志格式。

    1、单文件日志

    import logging
    logging.basicConfig(filename='log.log',
                        format='%(asctime)s-%(name)s-%(levelname)s-%(module)s:%(message)s',
                        datefmt='%Y-%m-%d %H:%M:%S %p',
                        level=10)
    logging.debug('d')
    logging.info('i')
    logging.warning('w')
    logging.error('e')
    logging.critical('c')
    logging.log(10,'log')
    ########执行结果:生成一个log日志文件,内容如下:##########
    
    2016-05-26 14:58:29 PM-root-DEBUG-module:d
    2016-05-26 14:58:29 PM-root-INFO-module:i
    2016-05-26 14:58:29 PM-root-WARNING-module:w
    2016-05-26 14:58:29 PM-root-ERROR-module:e
    2016-05-26 14:58:29 PM-root-CRITICAL-module:c
    2016-05-26 14:58:29 PM-root-DEBUG-module:log

    注:只有【当前写等级】大于等于【日志等级】时,日志文件才被记录。

    日志等级:

    CRITICAL = 50
    FATAL = CRITICAL
    ERROR = 40
    WARNING = 30
    WARN = WARNING
    INFO = 20
    DEBUG = 10
    NOTSET = 0

    注:可以给日志对象(Logger Instance)设置日志级别,低于该级别的日志消息将会被忽略,也可以给Hanlder设置日志级别,对于低于该级别的日志消息, Handler也会忽略。

    import logging
    logging.basicConfig(filename = os.path.join(os.getcwd(), 'log.txt'), level = logging.DEBUG)
    logging.debug('this is a message')
    
    运行上面例子的代码,将会在程序的根目录下创建一个log.txt文件,打开该文件,里面有一条日志记录:”DEBUG:root:this is a message”。
    4个主要的组件
    logger: 日志类,应用程序往往通过调用它提供的api来记录日志;
    handler: 对日志信息处理,可以将日志发送(保存)到不同的目标域中;
    filter: 对日志信息进行过滤;
    formatter:日志的格式化,即日志记录的格式;

    a、loggers

    Logger.setLevel(lel):指定最低的日志级别,低于lel的级别将被忽略。debug是最低的内置级别,critical为最高
    Logger.addFilter(filt)、Logger.removeFilter(filt):添加或删除指定的filter
    Logger.addHandler(hdlr)、Logger.removeHandler(hdlr):增加或删除指定的handler
    Logger.debug()、Logger.info()、Logger.warning()、Logger.error()、Logger.critical():可以设置的日志级别

    b、Handlers

    handler对象负责发送相关的信息到指定目的地。可以通过addHandler()方法添加多个多handler
    Handler.setLevel(lel):指定被处理的信息级别,低于lel级别的信息将被忽略
    Handler.setFormatter():给这个handler选择一个格式
    Handler.addFilter(filt)、Handler.removeFilter(filt):新增或删除一个filter对象

    c、filters

    d、Formatter对象设置日志信息最后的规则、结构和内容,默认的时间格式为%Y-%m-%d %H:%M:%S,下面是Formatter常用的一些信息

    %(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

    用户输出的消息

    logging模块中的常用函数:

    logging.basicConfig([**kwargs]):

    为日志模块配置基本信息。kwargs 支持如下几个关键字参数:

      • filename :日志文件的保存路径。如果配置了些参数,将自动创建一个FileHandler作为Handler;
      • filemode :日志文件的打开模式。 默认值为'a',表示日志消息以追加的形式添加到日志文件中。如果设为'w', 那么每次程序启动的时候都会创建一个新的日志文件;
      • format :设置日志输出格式;
      • datefmt :定义日期格式;
      • level :设置日志的级别.对低于该级别的日志消息将被忽略;
      • stream :设置特定的流用于初始化StreamHandler;

    深入了解,点击:http://www.jb51.net/article/50368.htm,http://www.jb51.net/article/68133.htm,http://blog.csdn.net/yatere/article/details/6655445

    需求:开发一个日志系统, 既要把日志输出到控制台, 还要写入日志文件,参考文章:http://www.jb51.net/article/42626.htm

    logging模块源码介绍:
    https://docs.python.org/2/library/logging.html
    # -*- coding: utf-8 -*-
    """
    A simple fibonacci program
    """
    import argparse
    parser = argparse.ArgumentParser(description='I print fibonacci sequence')
    parser.add_argument('-s', '--start', type=int, dest='start',
                        help='Start of the sequence', required=True)
    parser.add_argument('-e', '--end', type=int, dest='end',
                        help='End of the sequence', required=True)
    parser.add_argument('-v', '--verbose', action='store_true', dest='verbose',
                        help='Enable debug info')
    import logging
    logger = logging.getLogger('fib')
    logger.setLevel(logging.DEBUG)
    hdr = logging.StreamHandler()
    formatter = logging.Formatter('[%(asctime)s] %(name)s:%(levelname)s: %(message)s')
    hdr.setFormatter(formatter)
    logger.addHandler(hdr)
    
    def infinite_fib():
        a, b = 0, 1
        yield a
        yield b
        while True:
            logger.debug('Before caculation: a, b = %s, %s' % (a, b))
            a, b = b, a + b
            logger.debug('After caculation: a, b = %s, %s' % (a, b))
            yield b
    
    def fib(start, end):
        for cur in infinite_fib():
            logger.debug('cur: %s, start: %s, end: %s' % (cur, start, end))
            if cur > end:
                return
            if cur >= start:
                logger.debug('Returning result %s' % cur)
                yield cur
    def main():
        args = parser.parse_args()
        if args.verbose:
            logger.setLevel(logging.DEBUG)
        else:
            logger.setLevel(logging.ERROR)
        for n in fib(args.start, args.end):
            print n,
    if __name__ == '__main__':
        main()
    用logging模块的斐波那契数列

    2、多文件日志

    对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。

    # 定义文件
    file_1_1 = logging.FileHandler('l1_1.log', 'a')
    fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s")
    file_1_1.setFormatter(fmt)
    
    file_1_2 = logging.FileHandler('l1_2.log', 'a')
    fmt = logging.Formatter()
    file_1_2.setFormatter(fmt)
    
    # 定义日志
    logger1 = logging.Logger('s1', level=logging.ERROR)
    logger1.addHandler(file_1_1)
    logger1.addHandler(file_1_2)
    
    
    # 写日志
    logger1.critical('1111')
    
    日志(一)
    日志一
    # 定义文件
    file_2_1 = logging.FileHandler('l2_1.log', 'a')
    fmt = logging.Formatter()
    file_2_1.setFormatter(fmt)
    
    # 定义日志
    logger2 = logging.Logger('s2', level=logging.INFO)
    logger2.addHandler(file_2_1)
    
    日志(二)
    日志二

    如上述创建的两个日志对象

    • 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
    • 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
  • 相关阅读:
    poj 3243 Clever Y(BabyStep GiantStep)
    poj 2417 Discrete Logging
    poj 3481 Double Queue
    hdu 4046 Panda
    hdu 2896 病毒侵袭
    poj 1442 Black Box
    hdu 2815 Mod Tree
    hdu 3065 病毒侵袭持续中
    hdu 1576 A/B
    所有控件
  • 原文地址:https://www.cnblogs.com/tina-python/p/5530565.html
Copyright © 2011-2022 走看看