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)
View Code
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'])          # 
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
View Code
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)
View Code

 

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('登录失败!')
View Code

 

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)单对文件流设置某个级别。
View Code

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))

你可能感兴趣的:(Python进阶-XVV hashlib模块、configparse模块、logging模块)