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 文件中
  • 相关阅读:
    Apache Maven ToolChains的使用
    小师妹学JavaIO之:文件读取那些事
    JDK9的新特性:JPMS模块化
    JDK9的新特性:String压缩和字符编码
    小师妹学JavaIO之:File copy和File filter
    JDK10的新特性:var和匿名类
    Flutter 完美的验证码输入框
    Flutter 不可错过的学习资源
    《Flutter 动画系列》组合动画
    【强烈推荐】适合Flutter初学者的完整项目
  • 原文地址:https://www.cnblogs.com/tina-python/p/5530565.html
Copyright © 2011-2022 走看看