Python进阶-XVV hashlib模块、configparse模块、logging模块
1、配置相关的configparse模块
配置文件如何组织?python中常见的是将配置文件写成py,然后引入该模块即可。优点是方便访问。
但是也有用类似windows中的ini文件的配置文件,了解即可,这就是configparser模块。
该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)。
1) 创建文件
1 import configparser 2 config = configparser.ConfigParser() 3 config['DEFAULT'] = { 4 'ServerAliveInterval': '45', 5 'Compression': 'yes', 6 'CompressionLevel': '9', 7 'ForwardX11':'yes' 8 } 9 config['funyou.net'] = {'admin': 'funyou'} 10 11 config['hongsun.com'] = {'Host port': '66066', 'Forward': 'True'} 12 13 with open('config.ini', 'w', encoding='utf-8') as config_file: 14 config.write(config_file)
2) 查找文件
查找文件内容,类似字典的形式
1 print(config.sections()) # [] 2 3 config.read('config.ini') 4 5 print(config.sections()) # ['funyou.net', 'hongsun.com'] 6 7 print('bytebong.com' in config) # False 8 print('funyou.net' in config) # True 9 10 11 print(config['funyou.net']["admin"]) # funyou 12 13 print(config['DEFAULT']['Compression']) #yes 14 15 print(config['hongsun.com']['ForwardX11']) #yes 自己没有会去找DEFAULT中的,如果没有报错! 16 17 18 print(config['hongsun.com']) # <Section: hongsun.com> 19 20 for key in config['hongsun.com']: # 注意,有default会默认default的键 21 print(key) 22 23 print(config.options('funyou.net')) # 同for循环,找到'funyou.net'下所有键(包含默认组中的) 24 25 print(config.items('funyou.net')) # 找到'funyou.net'下所有键值对(包含默认组中的) 26 27 print(config.get('funyou.net','compression')) # yes get方法Section下的key对应的value
3)增删改操作
1 config.add_section('typhoon.org') 2 3 config.remove_section('funyou.net') 4 config.remove_option('typhoon.org',"forwardx11") 5 6 config.set('typhoon.org','admin','typhoon') 7 config.set('typhoon.org', 'super admin', 'json') 8 with open('setting.ini', "w") as c_f: 9 config.write(c_f)
2、加密相关的hashlib模块
1 # 1、使用场景 2 # 1)加密需要保护的数据:如登录密码 3 # 2)比较文件的一致性 4 5 # 2、hashlib模块标准使用流程 6 7 # 1)、导入模块 8 import hashlib 9 # 2)得到md5(或其他算法)对象 10 md5 = hashlib.md5() 11 sha1 = hashlib.sha1() 12 str = b'1432342afsd' 13 # 3)将二进制的对象,放入进行更新 14 md5.update(str) 15 sha1.update(str) 16 # 4)进行消化,得到加密结果 17 print(md5.hexdigest(), sha1.hexdigest()) 18 19 # 不管算法多么不同,摘要的功能始终不变 20 # 对于相同的字符串使用同一个算法进行摘要,得到的值总是不变的 21 # 使用不同算法对相同的字符串进行摘要,得到的值应该不同 22 # 不管使用什么算法,hashlib的方式永远不变 23 24 # sha 算法 随着 算法复杂程度的增加 我摘要的时间成本空间成本都会增加 25 26 27 # 3、加盐 为了对付如下情况: 28 # 虽然MD5摘要算法,是不可逆的,但是有人用穷举法, 29 # 将大部分可能的字符组合对应的加密结果放入数据库中。即撞库! 30 md5 = hashlib.md5(b'salt') 31 32 # 4、动态加盐,将一些固定的字符串,取其一部分作为盐撒进去! 33 # import hashlib # 提供摘要算法的模块 34 md5 = hashlib.md5(bytes('盐',encoding='utf-8')+b'') 35 # md5 = hashlib.md5() 36 md5.update(b'123456') 37 print(md5.hexdigest()) 38 39 # 5、可以将要加密的内容分开进行update,这跟一次update结果一样, 40 # 适合文件一致性比较,文件内容很多,可以分成好多次update,但是结果是相同的 41 with open('1_复习昨天内容.py', mode='rb') as f: 42 for line in f.readlines(): 43 md5.update(bytes(line)) 44 print(md5.hexdigest()) 45 # 文件的一致性校验 不用加盐 46 47 # 6、典型应用,用户注册和登录 48 account = input('请输入登录账号:》》》').strip() 49 pwd = input('请输入登录密码:》》》').strip() 50 md5 = hashlib.md5(b'sl'+bytes(account[2:],encoding='utf-8')) 51 md5.update(bytes(pwd, encoding='utf-8')) 52 md5_pwd = md5.hexdigest() 53 #注册部分 54 # with open('userinfo',mode='w', encoding='utf-8') as f: 55 # f.write('%s|%s'%(account, md5_pwd)) 56 # 登录部分 57 with open('userinfo', encoding='utf-8') as f: 58 for line in f.readlines(): 59 name, pwd_md5 = line.split('|') 60 if account == name and pwd_md5 == md5_pwd: 61 print('登录成功!') 62 else: 63 print('登录失败!')
3、日志相关的logging模块
0) 标准配置
1 import logging 2 from conf.my_log_settings import * 3 4 logger = logging.getLogger() 5 logger.setLevel(logging.DEBUG) 6 7 if not logger.handlers: 8 9 fh = logging.FileHandler(filename=log_file, mode='a', encoding='utf-8') 10 sh = logging.StreamHandler() 11 12 formatter = logging.Formatter(fmt='%(asctime)s / %(name)s / %(levelname)s /line_no:[%(lineno)d] / %(message)s', 13 datefmt='%Y-%m-%d %X') 14 15 fh.setFormatter(formatter) 16 sh.setFormatter(formatter) 17 18 logger.addHandler(fh) 19 logger.addHandler(sh)
1)初步配置
1 import logging 2 3 # 默认情况下Python的logging模块将日志打印到了标准输出中,且只显示了大于等于WARNING级别的日志, 4 # 这说明默认的日志级别设置为WARNING(日志级别等级CRITICAL > ERROR > WARNING > INFO > DEBUG), 5 # 默认的日志格式为日志级别:Logger名称:用户输出消息。 6 7 # 1) 基本配置 缺点:只能在文件中查看,无法打印到屏幕上 8 9 # 创建一个handler,用于写入日志文件 10 file_handler = logging.FileHandler(filename='x.log', mode='a', encoding='utf-8') 11 # logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', 12 # datefmt='%Y-%m-%d %H:%M:%S %p', 13 # handlers=[file_handler,], 14 # level=logging.DEBUG 15 # ) 16 17 # 2)高级配置 使用logger对象 18 logger = logging.getLogger() 19 # 再创建一个handler,用于输出到控制台 20 stream_handler = logging.StreamHandler() 21 22 formatter_1 = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') 23 formatter_2 = logging.Formatter('%(asctime)s / %(name)s / %(levelname)s /[line_No]%(lineno)d / %(message)s') 24 25 file_handler.setFormatter(formatter_1) 26 stream_handler.setFormatter(formatter_2) 27 28 logger.addHandler(file_handler) #logger对象可以添加多个fh和ch对象 29 logger.addHandler(stream_handler) 30 31 logging.debug("this is debug message") 32 logging.info("this is info message") 33 logging.warning("this is warning message") 34 logging.error("this is error(错误) message") 35 logging.critical("this is critical message") 36 37 # logging库提供了多个组件:Logger、Handler、Filter、Formatter。Logger对象提供应用程序可直接使用的接口, 38 # Handler发送日志到适当的目的地,Filter提供了过滤日志信息的方法,Formatter指定日志显示格式。另外,可以通过: 39 # logger.setLevel(logging.Debug)设置级别,当然,也可以通过 fh.setLevel(logging.Debug)单对文件流设置某个级别。
2)配制参数详解
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用户输出的消息
3)分割日志存储
1 import time,logging 2 from logging import handlers 3 4 # 日志切割,当日志达到一定条数后,写入新的日志中取,名字在原日志后加时间:hongsun.log.2019-12-18_22-08-23 5 6 s_handler = logging.StreamHandler() 7 r_f_handler = handlers.RotatingFileHandler('funyou.log', maxBytes=1024, backupCount=25, encoding='utf-8') 8 t_r_f_handler = handlers.TimedRotatingFileHandler(filename='hongsun.log', when='s', interval=25, encoding='utf-8') 9 logging.basicConfig( 10 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', 11 datefmt='%Y-%m-%d %H:%M:%S %p', 12 handlers=[t_r_f_handler, s_handler, r_f_handler], 13 level=logging.ERROR 14 ) 15 16 for i in range(1, 100): 17 time.sleep(1) 18 logging.error('KeyboardInterrupt error %s'%str(i))

浙公网安备 33010602011771号