欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

shutil模块,logging模块

程序员文章站 2022-03-25 20:17:11
shutil模块: logging模块: ......

shutil模块:

    import shutil
    # 拷贝文件
     shutil.copy2('原文件', '现文件')
     shutil.copy2('file', 'temp')
        #示例:
        shutil.copy2('d:\python22\day21\lianjia.html', 'd:\python22\day21\lianjia_bk.html')

    # 拷贝目录
     shutil.copytree("原目录", "新目录", ignore=shutil.ignore_patterns("*.pyc"))
     shutil.copytree("/users/jingliyang/pycharmprojects/面试题/常用模块/logging模块", "logging模块2", ignore=shutil.ignore_patterns("__init__.py"))
         #示例:
         shutil.copytree("outer","outer3",ignore=shutil.ignore_patterns("__init__.py","sag")) #第三个参数可不写, *.py 表示所有py文件都不拷贝  *.mp4 表示所有mp4文件都不拷贝

    # 删除目录
     shutil.rmtree("temp", ignore_errors=true)
     shutil.rmtree("logging模块2", ignore_errors=true)

    # 移动文件/目录
     shutil.move("logging模块", "logging2", copy_function=shutil.copy2)

    # 获取磁盘使用空间
     total, used, free = shutil.disk_usage(".")
     print("当前磁盘共: %igb, 已使用: %igb, 剩余: %igb"%(total / 1073741824, used / 1073741824, free / 1073741824))
    
    # 压缩文件
     shutil.make_archive('压缩文件夹的名字', 'zip','待压缩的文件夹路径')
     shutil.make_archive('logging2', 'zip','/users/jingliyang/pycharmprojects/面试题/常用模块/随机数')

    # 解压文件
     shutil.unpack_archive('zip文件的路径.zip','解压到目的文件夹路径')
     shutil.unpack_archive('/users/jingliyang/pycharmprojects/面试题/常用模块/shutil模块/logging2.zip','/users/jingliyang/pycharmprojects/面试题/常用模块/shutil模块/tmp')


    参考资料
    https://docs.python.org/3/library/shutil.html
    https://segmentfault.com/a/1190000016689023?utm_source=tag-newest

logging模块:

    # 为什么要写log?
        # log是为了排错
        # log用来做数据分析的

        # 购物商城 - 数据库里
            # 什么时间购买了什么商品
            # 把哪些商品加入购物车了

        # 做数据分析的内容 - 记录到日志
        # 1.一个用户什么时间在什么地点 登录了购物程序
        # 2.搜索了哪些信息,所长时间被展示出来了
        # 3.什么时候关闭了软件
        # 4.对哪些商品点进去看了
    
     项目中一定要写日志,写日志的用途:
     1.用来记录用户的行为 - 数据分析
     2.用来记录用户的行为 - 操作审计
     3.排查代码中的错误
    
    
   函数式简单配置:

       输出内容是有等级的 : 默认处理warning级别以上的所有信息
       默认情况下python的logging模块将日志打印到了标准输出中,且只显示了大于等于warning级别的日志,这说明默认的日志级别设置为warning(日志级别等级critical > error > warning > info > debug),默认的日志格式为日志级别:logger名称:用户输出消息。
         
         import logging
         logging.debug('debug message')          # 调试
         logging.info('info message')            # 信息
         logging.warning('warning message')      # 警告
         logging.error('error message')          # 错误
         logging.critical('critical message')    # 批判性的
        
        #运行结果;
          warning:root:warning message
          error:root:error message
          critical:root:critical message


        debug信息在写程序时仍然要写,在正常运行过程中不让其写入文件或打印显示。等出现了问题,把程序重启,打开调试模式,然后把问题复现,查看日志内容。
        在多个函数协同工作时,快速直接定位到出问题的函数。
        #例:
         def cal_mul(exp):
             exp = 4*6
             logging.debug('4*6 = 24')
             return 24
         def cal_div():
             pass
         def cal_add():
             pass
         def cal_sub(exp):
             exp = 3-24
             logging.debug('cal_sub :3-24 = 21')
             return 21
        
         def cal_inner_bracket(exp2):
             exp2 = 3-4*6
             ret = cal_mul(4*6)
             exp2 = 3-24
             ret = cal_sub(3-24)
             logging.debug('3-4*6 = -21')
             return -21
        
         def main(exp):
             exp =(1+2*(3-4*6))/5
             ret = cal_inner_bracket(3-4*6)
             return ret
        
         logging.basicconfig(level=logging.debug)  #设置参数,通过level设置等级为debbug
         ret = main('(1+2*(3-4))/5')
         print(ret)
        结果:
        # debug:root:4*6 = 24
        # debug:root:cal_sub :3-24 = 21
        # debug:root:3-4*6 = -21

         无论你希望日志里打印哪些内容,都得你自己写,没有自动生成日志这种事儿。在你觉着可能出问题的地方 或者在排错时可能会用到的地方写一个日志 【记】
        
        
    日志的格式:通过logging.basicconfig设置,来灵活配置日志级别,日志格式,输出位置:

        1.输出到屏幕:
        
        import logging
        logging.basicconfig(format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',datefmt='%y-%m-%d %h:%m:%s %p')
        # asctime表示时间,字符串形式的当前时间;name表示哪个用户启动的程序,logger的名字;levelname表示日志等级,lineno调用日志输出函数的语句所在的代码行文本形式的日志级别,module表示调用日志输出函数的模块名,message表示你要打印的信息,用户输出的消息。datefmt描述时间能使用的格式
         logging.warning('warning message test2')
         logging.error('error message test2')
         logging.critical('critical message test2')
        #结果:
            2019-05-29 23:44:01 pm - root - warning[line :56]-tt21:  warning message test2
            2019-05-29 23:44:01 pm - root - error[line :57]-tt21:  error message test2
            2019-05-29 23:44:01 pm - root - critical[line :58]-tt21:  critical message test2


        2.输出到文件,并且设置信息的等级:  一般情况下,文件以 .log结尾
             
            logging.basicconfig(format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',datefmt='%y-%m-%d %h:%m:%s %p',filename='tmp.log',level= logging.debug)
             logging.debug('debug 信息错误 test2')
             logging.info('info 信息错误 test2')
             logging.warning('warning message test2')
             logging.error('error message test2')
             logging.critical('critical message test2')
            
            # 写入到了文件中,但是有乱码。向文件中写入内容是默认是追加模式,前面的内容不会清空
            # debug和info等级的信息没有写入,设置级别后就可以。level= logging.debug


       3. 同时向文件和屏幕上输出 ,并解决乱码问题 【记】【重点】
            
            fh = logging.filehandler('tmp.log',encoding='utf-8')  #filehandler操作文件的操作符,()内放入日志文件名,编码方式;对应变量放入handlers=[fh,sh]
            # fh2 = logging.filehandler('tmp2.log',encoding='utf-8')  #同样的日志内容可以输出到多个不同的文件中,对应变量放入handlers=[fh,sh,fh2](了解)
            sh = logging.streamhandler()  #streamhandler屏幕操作符,不用加参数,对应变量放入handlers=[fh,sh]
            logging.basicconfig(
                format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',
                datefmt='%y-%m-%d %h:%m:%s %p',
                level= logging.debug,   #一般没有问题不会调到debug模式
                # handlers=[fh,sh,fh2]
                handlers=[fh,sh]
            )#handlers=[fh,sh]放文件操作符和屏幕操作符
            logging.debug('debug 信息错误 test2')
            logging.info('info 信息错误 test2')
            logging.warning('warning message test2')
            logging.error('error message test2')
            logging.critical('critical message test2')
            #结果:
            # 2019-05-30 00:05:34 am - root - debug[line :88]-tt21:  debug 信息错误 test2
            # 2019-05-30 00:05:34 am - root - info[line :89]-tt21:  info 信息错误 test2
            # 2019-05-30 00:05:34 am - root - warning[line :90]-tt21:  warning message test2
            # 2019-05-30 00:05:34 am - root - error[line :91]-tt21:  error message test2
            # 2019-05-30 00:05:34 am - root - critical[line :92]-tt21:  critical message test2


         4.做日志的切分(日志切割):每隔一段时间形成一个文件,切分出来。(项目中一般用此来写日志,平时可用上面的方式)【记】
            import time
            import logging
            from logging import handlers
            
            sh = logging.streamhandler()  #输出到屏幕
            rh = handlers.rotatingfilehandler('myapp.log', maxbytes=1024,backupcount=5)   # 按照大小做切割,如按1kb切割,每次切割1kb,放入myapp.log里,设置最多切5个文件,只保留最近的5个,避免磁盘满了
            fh = handlers.timedrotatingfilehandler(filename='x2.log', when='s', interval=5, encoding='utf-8') #按时间切,放入x2.log里,如when按照秒来切,每5秒切一个。默认按小时切。
            logging.basicconfig(
                format='%(asctime)s - %(name)s - %(levelname)s[line :%(lineno)d]-%(module)s:  %(message)s',
                datefmt='%y-%m-%d %h:%m:%s %p',
                level= logging.debug,
                # handlers=[fh,sh,fh2]
                handlers=[fh,rh,sh]
            )
            
            for i in range(1,100000):  #每秒钟写一个信息,总共写10万个
                time.sleep(1)
                logging.error('keyboardinterrupt error %s'%str(i))


      配置参数:


        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用户输出的消息