zoukankan      html  css  js  c++  java
  • hashlib ,configparser , logging 模块

    hash: 算法, 结果是什么? 是内存地址,
    print(hash('123'))
    dic = {'name':'alex'}
    print(hash('name'))
    print(id('name'))
    View Code
    hashlib 模块 与加密相关,被称作 摘要算法.:
    1,是一堆算法的合集,他包含很多算法(加密的).
    2,hashlib的过程就是将字符串转化成---->数字的过程.
    3,hashlib对相同的字符串转化成的数字相同.
    4,不同的电脑,对相同的字符串进行 加密 转化成的数字相同.
    
    用在哪里?
    1,密文(密码).
        将密码用算法加密放置到数据库,每次取出验证.
    2,文件的校验.
    
    初识 hashlib:
    import hashlib
    md5 加密算法:  常用算法, 可以满足一般的常用的需求
    sha 加密算法:  级别高一些, 数字越大级别越高,加密的效率越低,越安全.
    md5:
    s1 = '12343254'
    ret = hashlib.md5()  # 创建一个md5对象
    ret.update(s1.encode('utf-8')) # 调用此update方法对参数进行加密 bytes类型
    print(ret.hexdigest())  # 得到加密后的结果 定长
    View Code
    s2 = 'alex12fdsl,.afjsdl;fjksdal;fkdsal;fld;lsdkflas;dkfsda;3'
    ret = hashlib.md5()  # 创建一个md5对象
    ret.update(s2.encode('utf-8')) # 调用此update方法对参数进行加密 bytes类型
    print(ret.hexdigest())  # 得到加密后的结果 定长
    View Code
    s3 = 'alex12fdsl,afjsdl;fjksdal;fkdsal;fld;lsdkflas;dkfsda;3'
    ret = hashlib.md5()  # 创建一个md5对象
    ret.update(s3.encode('utf-8')) # 调用此update方法对参数进行加密 bytes类型
    print(ret.hexdigest())  # 得到加密后的结果 定长
    View Code
    无论字符串多长,返回都是定长的数字,
    同一字符串,MD5值相同.
    闲人: 将你常用的密码 000000  111111   890425
    对应关系表:
    000000     c108971251713ee7c59db5c097378018
    撞库: 因为撞库,所以相对不安全,如何解决?
    s4 = '123456'
    ret = hashlib.md5()  # 创建一个md5对象
    ret.update(s4.encode('utf-8'))
    print(ret.hexdigest())  # e10adc3949ba59abbe56e057f20f883e
    View Code
    解决方式:加盐.
    s3 = '123456'
    ret = hashlib.md5('@$1*(^&@^2wqe'.encode('utf-8'))  # 创建一个md5对象,加盐
    ret.update(s3.encode('utf-8')) # 调用此update方法对参数进行加密 bytes类型
    print(ret.hexdigest())  # 得到加密后的结果 定长 c5f8f2288cec341a64b0236649ea0c37
    
    如果黑客盗取到你的固定盐 '@$1*(^&@^2wqe'内容
    View Code
    变成随机的盐(动态加盐):
    username = '张三'
    password = '123456'
    
    ret = hashlib.md5(username[::-1].encode('utf-8'))
    ret.update(password.encode('utf-8'))
    print(ret.hexdigest())
    View Code
    sha 系列:
    hashlib.sha1()  #  sha1 与md5 级别相同,但是sha1比md5 更安全一些,
    ret = hashlib.sha1()
    ret.update('123456'.encode('utf-8'))
    print(ret.hexdigest())  # 7c4a8d09ca3762af61e59520943dc26494f8941b
    
    ret = hashlib.sha512()  #级别最高,效率低,安全性最大
    ret.update('123456'.encode('utf-8'))
    print(ret.hexdigest())  # ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413
    View Code
    文件的校验:
    对于小文件可以,但是超大的文件内存受不了,(下面具体代码解决)
    def func(file_name):
        with open(file_name,mode='rb') as f1:
            ret = hashlib.md5()
            ret.update(f1.read())
            return ret.hexdigest()
    
    print(func('hashlib_file'))
    print(func('hashlib_file1'))
    
    s1 = 'I am 旭哥, 都别惹我.... 不服你试试'
    ret = hashlib.md5()
    ret.update(s1.encode('utf-8'))
    print(ret.hexdigest())  # 15f614e4f03312320cc5cf83c8b2706f
    
    s1 = 'I am 旭哥, 都别惹我.... 不服你试试'
    ret = hashlib.md5()
    ret.update('I am'.encode('utf-8'))
    ret.update(' 旭哥, '.encode('utf-8'))
    ret.update('都别惹我....'.encode('utf-8'))
    ret.update(' 不服你试试'.encode('utf-8'))
    print(ret.hexdigest())  # 15f614e4f03312320cc5cf83c8b2706f
    View Code
    超大大文件:
    def func(file_name):
        with open(file_name,mode='rb') as f1:
            ret = hashlib.md5()
            while True:
                content = f1.read(1024)
                if content:
                    ret.update(content)
                else:
                    break
            return ret.hexdigest()
    print(func('hashlib_file'))
    print(func('hashlib_file1'))
    View Code
    hashlib:总结
    用在 密文,或者文件的校验.
    md5 :普通的,加盐的,动态加盐的
    sha 系列:普通的,加盐的,动态加盐的
    文件的校验:小文件,大文件
    configparser模块:
    帮助你操作(创建,增,删,改,查)一个配置文件
    创建一个文件.
    import configparser
    
    config = configparser.ConfigParser()
    
    config["DEFAULT"] = {'ServerAliveInterval': '45',
                          'Compression': 'yes',
                         '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)
    View Code
    import configparser
    
    config = configparser.ConfigParser()
    
    ---------------------------查找文件内容,基于字典的形式
    
    print(config.sections())        #  []
    
    config.read('example.ini')
    顺序:创建一个对象,然后将文件读到内存中,在进行相应的操作.
    
    print(config.sections())        #   ['bitbucket.org', 'topsecret.server.com']
    # #为什么没有 DEFAULT,它是特殊的,可以看做成一个全局的.
    print('111' in config) # False
    print('bitbucket.org' in config) # True
    判断节名是否在配置文件中 上面的方法
    View Code
    对配置文件中的节对应的项 取值:
    print(config['bitbucket.org']["user"])  # hg
    
    print(config['DEFAULT']['Compression']) #yes
    
    print(config['topsecret.server.com']['ForwardX11'])  #no
    
    
    print(config['bitbucket.org'])          #<Section: bitbucket.org> 可迭代对象
    print(config['bitbucket.org']['forwardx11'])          #<Section: bitbucket.org> 可迭代对象
    
    for key in config['bitbucket.org']:     # 注意,有default会默认default的键
        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
    View Code
    增删改:
    import configparser
    
    config = configparser.ConfigParser()
    config.read('new2.ini')
    config.add_section('日天')
    config.remove_section('bitbucket.org')
    config.remove_option('topsecret.server.com',"forwardx11")
    
    
    config.set('topsecret.server.com','k1','11111')
    config.set('yuan','k2','22222')
    
    config.write(open('new2.ini', "w"))
    View Code
    logging 模块:
    log 日志:
    什么时候用到日志?
    生活中:
    1, 公司员工信息工号等等需要日志.
    2, 淘宝,京东 你的消费信息,浏览记录等等都记录日志中,个性化推荐.
    3, 头条个性化设置(爱好记录的日志中).
    
    工作上:
    运维人员,任何员工对服务器做过的任何操作,都会记录到日志中.
    如果你要是从事运维开发的工作,各处都需要日志.
    debug模式,需要依靠日志的.
    定时收集信息,也要记录日志.
    
     logging 模块是辅助你记录日志的,不是自动记录日志的.
        低配版,logging
        高配版,logger 对象
    
    低配版,logging:
    import logging
    等级是一层一层升高的.:
    logging.basicConfig(level=logging.ERROR)
    # level=logging.DEBUG 设置显示报错的级别.
    logging.debug('debug message')   # 调试信息
    logging.info('info message')    # 正常信息
    logging.warning('warning message')  # 警告信息:代码虽然不报错,但是警告你写的不规范,必须改.
    logging.error('error message')  # 错误信息.
    logging.critical('critical message') # 严重错误信息.
    View Code
    用法实例:
    try:
        num = input('>>>请输入')
        num = int(num)
    except ValueError:
        logging.error('出现了 %s' % ValueError)
    View Code
    1,调整格式.(完善报错信息)
    ogging.basicConfig(level=logging.DEBUG,
                        format='%(asctime)s %(filename)s (line:%(lineno)d) %(levelname)s %(message)s',
                        )
    # level=logging.DEBUG 设置显示报错的级别.
    logging.debug('debug message')   # 调试信息
    logging.info('info message')    # 正常信息
    logging.warning('warning message')  # 警告信息:代码虽然不报错,但是警告你写的不规范,必须改.
    logging.error('error message')  # 错误信息.
    logging.critical('critical message') # 严重错误信息.
    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='low_logging.log',
                        # filemode='w',
                        )
    logging.warning('warning 警告错误!!!!')  # 警告信息:代码虽然不报错,但是警告你写的不规范,必须改.
    logging.error('error message')  # 错误信息.
    logging.critical('critical message') # 严重错误信息.
    level=logging.DEBUG 设置显示报错的级别.
    try:
        num = input('>>>请输入')
        num = int(num)
    except Exception as e:
        logging.warning(e)  # 警告信息:代码虽然不报错,但是警告你写的不规范,必须改.
        logging.error(e)  # 错误信息.
        logging.critical(e) # 严重错误信息.
    View Code
    low logging 缺点:
    1,写入文件 打印日志不能同时进行.
    2 ,写入文件时文件编码方式为gbk..
    1,被动触发: 与异常处理配合.访问记录.
    2, 主动触发:检测运维人员输入的指令,检测服务器的重要信息,访问记录.等等.
    
    低配版 low版:
    
    
    import logging
    logging.basicConfig(level=logging.INFO,
                        format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
                        filename='low版logging.log'
                        )
    msg = 'cpu 正常,硬盘参数...,流量的max:..最小值:.....'
    logging.info(msg)
    View Code
    日志的信息:不能写入文件与显示 同时进行.
    高配版:
    第一版:只输入文件中.
    import logging
    logger = logging.getLogger() # 创建logger对象.
    fh = logging.FileHandler('高配版logging.log',encoding='utf-8')  # 创建文件句柄
    
    # 吸星大法
    logger.addHandler(fh)
    
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    View Code
    第二版:文件和屏幕都存在.
    import logging
    logger = logging.getLogger() # 创建logger对象.
    fh = logging.FileHandler('高配版logging.log',encoding='utf-8')  # 创建文件句柄
    sh = logging.StreamHandler()  #产生了一个屏幕句柄
    
    # 吸星大法
    logger.addHandler(fh)  #添加文件句柄
    logger.addHandler(sh)  #添加屏幕句柄
    
    
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    View Code
    第三版:文件和屏幕都存在的基础上 设置显示格式.
    import logging
    logger = logging.getLogger() # 创建logger对象.
    fh = logging.FileHandler('高配版logging.log',encoding='utf-8')  # 创建文件句柄
    sh = logging.StreamHandler()  #产生了一个屏幕句柄
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    
    # 吸星大法
    logger.addHandler(fh)  #添加文件句柄
    logger.addHandler(sh)  #添加屏幕句柄
    sh.setFormatter(formatter)  # 设置屏幕格式
    fh.setFormatter(formatter)  # 设置文件的格式  (这两个按照需求可以单独设置)
    
    
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    View Code
    第四版 文件和屏幕都存在的基础上 设置显示格式.并且设置日志水平
    import logging
    logger = logging.getLogger() # 创建logger对象.
    fh = logging.FileHandler('高配版logging.log',encoding='utf-8')  # 创建文件句柄
    sh = logging.StreamHandler()  #产生了一个屏幕句柄
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    logger.setLevel(logging.DEBUG)    # logger  总开关
    如果你对logger对象设置日志等级.那么文件和屏幕都设置了.
    总开关 默认从warning开始,如果想设置分开关:必须要从他更高级:(ERROR,critical)从这来个开始.
    
    吸星大法
    logger.addHandler(fh)  #添加文件句柄
    logger.addHandler(sh)  #添加屏幕句柄
    sh.setFormatter(formatter)  # 设置屏幕格式
    fh.setFormatter(formatter)  # 设置文件的格式  (这两个按照需求可以单独设置)
    fh.setLevel(logging.DEBUG)    #  fh ,sh 分开关
    
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    View Code
    hashlib模块:
    hash()
    把一个数据类转换成一个数字的算法
    在同一次执行的过程中,对同一个可hash的值进行计算得出的结果总是相同的
    做什么用的?
    有什么特点?
    基础数据类型的时候
    不可变数据类型可hash
    可变数据类型不可hash
    在数据的存储方面提供优化的
    为什么对同一个值计算hash值每次运行结果不同?
    由于每一次执行所获得的存储空间都不一定相同,所以多次执行同一代码得到的hash值可能不同
    hashlib的特点:
    是一个模块,提供多种算法  md5 sha
    单项不可逆
    同一个字符串用同一种算法进行加密,结果总是相同的
    同一个字符串用不同的算法进行加密,结果总是不同的
    那为什么要使用hashlib进行加密呢?
    1,登录
    alex3714 --> 转换-->转化之后的结果储存在文件里
    用户登录的时候
    输入密码-->用同样的方法转换-->结果于文件中的匹配
    import hashlib
    hashlib.md5()
    hashlib.sha()
    md5算法,sha算法
    字符串-->加密的结果
    md5算法——暴力破解,撞库
    sha算法是一个算法集,随着后面的数字越大,计算时间越长,结果越长,越安全
    我们以常见的摘要算法MD5为例,计算出一个字符串的MD5值:
    import hashlib
    md5 = hashlib.md5()
    md5.update('how to use md5 in python hashlib?')
    print md5.hexdigest()#d26a53750bc40b38b65a520292f69306
    View Code
    果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:
    md5 = hashlib.md5()
    md5.update('how to use md5 in ')
    md5.update('python hashlib?')
    print md5.hexdigest()
    import hashlib
    md5_obj = hashlib.md5()
    md5_obj.update(b'alex3174')
    print(md5_obj.hexdigest())#7cfb3c340e59a1f7c31cacedfd72a17c
    View Code
    简单登录练习:
    import hashlib
    user = input('username:')
    pwd = input('password:')
    md5_obj = hashlib.md5()
    md5_obj.update(pwd.encode('utf-8'))
    str_md5 = md5_obj.hexdigest()
    with open('userinfo')as f:
        for line in f:
            name,passwd = line.split('|')
            if name == user and str_md5 == passwd:
                print('登录成功')
                break
    View Code
    sha算法
    import hashlib
    md5_obj = hashlib.sha1()
    md5_obj.update(b'alex3714')
    print(md5_obj.hexdigest())
    
    import hashlib
    md5_obj = hashlib.md5()
    md5_obj.update(b'123456')
    print(md5_obj.hexdigest())
    View Code
    密码加盐
    import hashlib
    md5_obj = hashlib.md5(''.encode('utf-8'))
    md5_obj.update(b'123456')
    print(md5_obj.hexdigest())
    #ed174e8009ddb0c0182ada42a6b9a5cc
    View Code
    简单登录练习:
    import hashlib
    username = input('username: ')
    password = input('password: ')
    md5_obj = hashlib.md5(''.encode('utf-8'))
    md5_obj.update(password.encode('utf-8'))
    md5_str = md5_obj.hexdigest()
    with open('userinfo') as f:
        for line in f:
            name,pwd = line.split('|')
            if name == username and pwd == md5_str:
                print('登录成功')
                break
    
    恶意注册  500个
    jinlaoban  123456
    View Code
    动态加盐
    每一个用户的密码的密文的盐都不一样
    import hashlib
    username = input('username: ')
    password = input('password: ')
    md5_obj = hashlib.md5(username.encode('utf-8'))
    md5_obj.update(password.encode('utf-8'))
    str_md5 = md5_obj.hexdigest()
    with open('userinfo') as f:
        for line in f:
            name,pwd = line.split('|')
            if name == username and pwd == str_md5:
                print('登录成功')
                break
    View Code
    md5第一个功能——登录验证
    md5算法和sha系列算法的用法
    登录的加密认证
    摘要算法的漏洞——撞库(不安全)
    加盐的摘要算法——恶意注册(相对安全)
    动态加盐的摘要算法——完美(最安全)
    md5的第二个功能
    import hashlib
    md5_obj = hashlib.md5()
    md5_obj.update(b'alex')
    md5_obj.update(b'3714')
    str_md5 = md5_obj.hexdigest()
    print(str_md5)
    with open(r'D:S12py笔记day221.复习.py',encoding='utf-8') as f:
        str_content = f.read()
        # print(str_content.encode('utf-8'))
        md5_obj = hashlib.md5()
        md5_obj.update(str_content.encode('utf-8'))
        print(md5_obj.hexdigest)
    aee949757a2e698417463d47acac93df
    View Code
    校验文件的一致性:md5 速度快
    摘要算法的特点:
    对同一个字符串的多次update的结果和对这个完整字符串一次update的结果相同
    如果一个文件的size比较大
    import hashlib
    import os
    with open(r'D:S12py笔记day221.复习.py',encoding='utf-8')as f:
        file_size = os.path.getsize(r'D:S12py笔记day221.复习.py')
        md5_obj = hashlib.md5()
        while file_size>0:
            str_content = f.read(1024)
        print(md5_obj.hexdigest())
    View Code
    configparser模块
    描述了一种配置文件
    自然后缀名。ini
    配置文件的格式[组名]项的名字 = 值
    该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键= 值)
    创建文件:
    来看一个好多软件的常见文档格式如下:
    [DEFAULT]   section 小节
    ServerAliveInterval = 45  userinfo = 'd://'
    Compression = yes
    CompressionLevel = 9
    ForwardX11 = yes
    
    [bitbucket.org]
    User = hg
    
    [topsecret.server.com]
    Port = 50022
    ForwardX11 = no
    如果想用python生成一个这样的文档怎么做呢?
    import configparser
    
    config = configparser.ConfigParser()
    
    config["DEFAULT"] = {'ServerAliveInterval': '45',
                          'Compression': 'yes',
                         '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)
    View Code
    查找文件:
    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
    print('bitbucket.org' in config) # True
    print(config['bitbucket.org']["user"])  # hg
    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的键
        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
    View Code
    增删改操作
    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")
    
    config.set('topsecret.server.com','k1','11111')
    config.set('yuan','k2','22222')
    
    config.write(open('new2.ini', "w"))
    View Code
    logging模块;
    写日志的模块
    在代码遇到问题的时候——写给程序员看的
    一些中间结果起到的排错作用
    需要打印出来——在排错的过程中
    在真正提供服务的时候——不需要
    记录一些用户的行为——写给用户看的
                   ——写给公司看的
    记录一个字符串
    写文件  print
    logging 模块
    格式规范
    帮你把日志的紧急情况进行分类
    函数式简单配置(五个写日志功能:紧急程度依次增加)
    import logging
    logging.debug('debug message')
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    View Code
    如果想调整日志信息显示情况,需要配置
    基础配置basicConfig:简单配置。不能输出中文,同时向文件屏幕输入
    使用logger对象的形式进行配置
    基础配置basicConfig
    logging.basicConfig(level = logging.DEBUG)
    format = '%(asctime)s %(filename)s[line:%(lineno)d]%(levelname)s %(message)s',
    filename = 'test.log'
    logging.debug('debug message')#调试的时候
    logging.info('info message')
    logging.warning('warning message')
    logging.error('error message')
    logging.critical('critical message')
    View Code
    显示级别:
    CRITICAL = 50
    FATAL = CRITICAL
    ERROR = 40
    WARNING = 30
    WARN = WARNINGINFO = 20
    DEBUG = 10
    NOTSET = 0
    View Code
    使用logger对象的形式进行配置
    getlogger 复杂,能实现高可定制
    单独配置三样东西
    logger 对象
    格式
    文件操作符/屏幕操作符
    格式 ->文件(屏幕)操作符 ->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')
    View Code
    import logging
    logger = logging.getLogger()
    人——练会了吸星大法
    fh = logging.FileHandler('log',encoding='utf-8')#创建了一个文件操作
    fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    fh.setFormatter(fmt)#给文件操作符设置一个格式
    logger.addHandler(fh)#给logger对象添加fh武功
    #在屏幕上输入
    sh = logging.StreamHandler()
    sh.setFormatter(fmt)
    logger.addHandler(sh)
    #logger.StreamHandler()创建了一个屏幕操作符
    logger.setLevel(logging.DEBUG)
    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')
    View Code
    灵活配置日志级别,日志格式,输出位置:
    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')
    View Code
  • 相关阅读:
    C++ UFT-8和GB2312间的转换
    ssh不输入密码
    thinkpad T480安装WIN7
    删除目录下的不规则文件
    使用组合的方式来创建新类, 并可以重新定制某些类的特定行为
    使用gradle 编译生成 apk出现的问题
    android studio 使用 SVN
    Fiddler 抓取 Genymotion 数据包
    在eclipse中查看android源代码
    计算 md5
  • 原文地址:https://www.cnblogs.com/ls13691357174/p/9275714.html
Copyright © 2011-2022 走看看