一、logging模块
1、logging作用
1. 控制日志级别
2. 控制日志格式
3. 控制输出的目标为文件
2、日志级别
1 logging.debug('debug日志') # 10 2 logging.info('info日志') # 20 3 logging.warning('warning日志') #30 4 logging.error('error日志')#40 5 logging.critical('critical日志') #50
3、示例
import logging # 1. logger对象: 负责生产各种级别的日志 logger1 = logging.getLogger('用户交易') # 日志名用来标识日志的与什么业务有关 # 2. filter对象: 过滤日志(很少使用) # 3. handler对象: 控制日志输出目标位置,以及编码标准 fh1 = logging.FileHandler('a1.log',encoding='utf-8') fh2 = logging.FileHandler('a2.log',encoding='utf-8') ch = logging.StreamHandler() # 4. formmater对象:控制日志的格式 formatter1 = logging.Formatter( fmt='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p' ) formatter2 = logging.Formatter( fmt='%(asctime)s - %(levelname)s : %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p' ) # 5. 绑定logger对象与handler对象 logger1.addHandler(fh1) logger1.addHandler(fh2) logger1.addHandler(ch) # 6. 绑定handler对象与formatter对象 fh1.setFormatter(formatter1) fh2.setFormatter(formatter1) ch.setFormatter(formatter2) # 7. 设置日志级别,有logger对象与handler对象两层关卡,必须都放行最终日志才会放行,通常二者级别相同 logger1.setLevel(10) fh1.setLevel(10) fh2.setLevel(10) ch.setLevel(10) # 8. 使用logger对象产生日志 logger1.info('ffffffff')
4、log配置字典
LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { #打印到终端的日志 'ch': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到终端 'formatter': 'simple' }, #打印到a1.log文件的日志 'fh1': { 'level': 'DEBUG', 'class': 'logging.FileHandler', # 保存到文件 'formatter': 'standard', 'filename': fh1_path, # 日志文件的路径 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, # 打印到a2.log文件的日志 'fh2': { 'level': 'DEBUG', 'class': 'logging.FileHandler', # 保存到文件 'formatter': 'simple', 'filename': fh2_path, # 日志文件的路径 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { '': { 'handlers': ['fh1', 'fh2', 'ch'], 'level': 'DEBUG', }, }, }
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
logging.config.dictConfig(settings.LOGGING_DIC) logger1=logging.getLogger('用户交易') #logger1-> fh1,fh2,ch logger1.info('复古风刚刚兴起') logger2=logging.getLogger('用户权限') #logger2-> fh1,fh2,ch logger2.error('TOm没有执行权限')
二、hashlib模块
十 hashlib模块 # 1、什么叫hash:hash是一种算法(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384,
SHA512 ,MD5 算法),该算法接受传入的内容,经过运算得到一串hash值 # 2、hash值的特点是: #2.1 只要传入的内容一样,得到的hash值必然一样=====>要用明文传输密码文件完整性校验 #2.2 不能由hash值返解成内容=======》把密码做成hash值,不应该在网络传输明文密码 #2.3 只要使用的hash算法不变,无论校验的内容有多大,得到的hash值长度是固定的
hash算法就像一座工厂,工厂接收你送来的原材料(可以用m.update()为工厂运送原材料),经过加工返回的产品就是hash值
import hashlib # 方法一、 # 1. 造出一个hash工厂 m = hashlib.md5() #=hashlib.sha256() # 2. 给工厂运送原材料 m.update('hello_baby'.encode('utf-8')) # 必须是bytes类型 m.update('love_you'.encode('utf-8')) # 3. 产出产品 print(m.hexdigest()) # 43a09074cc658f190d053f223dcb4497 # 方法二、 # 1. 造出一个hash工厂 m = hashlib.md5('hello_baby'.encode('utf-8')) # 2. 给工厂运送原材料 m.update('love_you'.encode('utf-8')) # 3. 产出产品 print(m.hexdigest()) # 43a09074cc658f190d053f223dcb4497
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
# 一、文件校验 m = hashlib.md5() with open('test.txt','rb') as f: for line in f: m.update(line) print(m.hexdigest()) # 二、密码加密 password = input('>>:').strip() m = hashlib.md5() m.update(password.encode('utf-8')) print(m.hexdigest()) # 密码加盐处理思想,可以在用户输入的密码中加入其他的字符,例如: password = input('>>:').strip() m = hashlib.md5() m.update('天王盖地虎'.encode('utf-8')) # 进行加盐处理 m.update(password.encode('utf-8')) print(m.hexdigest())
# hmac 模块,用于强制性的加盐处理 import hmac m = hmac.new('宝塔镇河妖'.encode('utf-8')) # new(必须要传入位置参数) m.update('abc154728'.encode('utf-8')) print(m.hexdigest())
三、shelve模块
shelve模块比pickle模块简单,只有一个open函数,返回类似字典的对象,可读可写;key必须为字符串,而值可以是python所支持的数据类型
1、shelve模块也是一种序列化模块,内部使用的是pickle模块,所以也存在跨平台性差的问题
2、特点:
只要提供一个文件名即可
读写的方式和字典一样
将数据以类似字典的形式在文件中读写
3、应用场景
在单击的程序中使用
4、使用方法
(1)序列化
1 import shelve 2 3 s1= shelve.open('a.txt') # 打开文件 4 s1['week']=["Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"] 5 s1['person']={"name": "Zero", "age": 8, "height": 180} # 写操作 6 s1.close() # 关闭文件
(2)反序列化
import shelve s2 = shelve.open('a.txt') # 打开文件 print(s2.get('week')) print(s2.get('person')) print(s2.get('person')['age']) # 读取文件中内容 s2.close() # 关闭文件
四、xml模块
1、XML全称:可扩展标记语言,标记指的是代表某种含义的字符 XML<>
2、为什么要用xml
(1)为能够在不同的平台间继续数据的交换
(2)为了使交换的数据能让对方看懂,就需要按照一定的语法规范来书写
3、语法格式
(1)任何的起始标签都必须有一个结束标签。
<tagname></tagname>
<tagname></tagname>
<tagname/> 简化写法
(2)可以采用另一种简化语法,可以在一个标签中同时表示起始和结束标签。这种语法是在大于符号之前紧跟一个斜线(/)。
例如<ABC/>:XML解析器会将其翻译成<ABC></ABC>。
(3)标签必须按合适的顺序进行嵌套,所以结束标签必须按镜像顺序匹配起始标签,这好比是将起始和结束标签看作是数学中的左右括号:在没有关闭所有的内部括号之前,是不能关闭外面的括号的。
(4)所有的特性都必须有值(特性指的是属性)。
1 <person name="aaa"> 2 </person>
(5)所有的特性都必须在值的周围加上双引号。
4、注意点
(1)最外层有且只有一个标签,这个标签为根标签
(2)第一行应该有文档声明,用于高速计算机怎么理解
例如:<?xml version="1.0" encoding="utf-8"?>
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 <person> 2 <sut1> 3 </stu1> 4 <sut2> 5 </stu2> 6 </person>
5、使用场景:
(1)配置文件
(2)常规的数据交换。 例如从服务器获取一段新闻
6、方法及属性
(1).ElementTree 表示整个文件的元素树 (2.)Element 表示一个节点 a.属性 text 开始标签和结束标签中间的文本 attrib 所有的属性 字典类型 tag 标签的名字 b.方法 get 获取某个属性的值
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
import xml.etree.ElementTree as et # 读取xml文档到内存中 得到一个包含所有数据的节点树 # 每一个标签就称之为一个节点 或 元素 tree = et.parse("text.xml") # 获取根标签 root = tree.getroot() # 获取所有的country print(root.find("country")) # 找的是第一个 print(root.findall("country")) # 找的是所有 # 获取字标签 print(root.iter("country")) for i in root.iter("country"): print(i) # 遍历整个xml for country in root: print(country.tag,country.attrib,country.text) for t in country: print(t.tag, t.attrib, t.text) print(root.find("country").get("name"))
7、增删改查
1.解析XML 查找标签 find 在子标签中获取名字匹配第一个 findall 在子标签中获取名字匹配的所有标签 iter(tagname) 在全文中查找[匹配的所有标签 返回一个迭代器 2.生成XML 用ElmentTree parse() 解析一个文件 getroot() 获取根标签 write() 写入到文件 3.修改xml set 一个属性 remove 一个标签 append 一个标签
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 # 读取到内存 2 tree = et.parse("text.xml") 3 for country in tree.findall("country"): 4 yeartag = country.find("year") 5 yeartag.text = str(int(yeartag.text) + 1) 修改标签文本 6 7 country.remove(country.find("year")) 删除标签 8 9 # 添加子标签 10 newtag = et.Element("newTag") 11 # 文本 12 newtag.text = "123" 13 #属性 14 newtag.attrib["name"] = "DSB" 15 #添加 16 country.append(newtag) 17 18 # 写回到内存 19 tree.write("text.xml",encoding="utf-8",xml_declaration=False)
8、生成xml文档
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 import xml.etree.ElementTree as et 2 # 创建根标签 3 root = et.Element("root") 4 # 创建节点树 5 t1 = et.ElementTree(root) 6 7 # 加一个peron标签 8 persson = et.Element("person") 9 persson.attrib["name"] = "yyh" 10 persson.attrib["sex"] = "man" 11 persson.attrib["age"] = "20" 12 persson.text = "这是一个person标签" 13 14 root.append(persson) 15 16 # 写入文件 17 t1.write("newXML.xml",encoding="utf-8",xml_declaration=True)
五、configparser模块
ConfigParser模块在python中用来读取配置文件,配置文件的格式跟windows下的ini配置文件相似,可以包含一个或多个节(section), 每个节可以有多个参数(键=值)。使用的配置文件的好处就是不用在程序员写死,可以使程序更灵活。
注意:在python 3 中ConfigParser
模块名已更名为configparser
configparser函数常用方法:
读取配置文件:
1 read(filename) #读取配置文件,直接读取ini文件内容 2 3 sections() #获取ini文件内所有的section,以列表形式返回['logging', 'mysql'] 4 5 options(sections) #获取指定sections下所有options ,以列表形式返回['host', 'port', 'user', 'password'] 6 7 items(sections) #获取指定section下所有的键值对,[('host', '127.0.0.1'), ('port', '3306'), ('user', 'root'), ('password', '123456')] 8 9 get(section, option) #获取section中option的值,返回为string类型 10 >>>>>获取指定的section下的option <class 'str'> 127.0.0.1 11 12 getint(section,option) 返回int类型 13 getfloat(section, option) 返回float类型 14 getboolean(section,option) 返回boolen类型
举例如下:
配置文件ini如下:
[logging] level = 20 path = server = [mysql] host=127.0.0.1 port=3306 user=root password=123456
注意,也可以使用:替换=
代码如下:
import configparser from until.file_system import get_init_path conf = configparser.ConfigParser() file_path = get_init_path() print('file_path :',file_path) conf.read(file_path) sections = conf.sections() print('获取配置文件所有的section', sections) options = conf.options('mysql') print('获取指定section下所有option', options) items = conf.items('mysql') print('获取指定section下所有的键值对', items) value = conf.get('mysql', 'host') print('获取指定的section下的option', type(value), value)
运行结果如下:
file_path : /Users/xxx/Desktop/xxx/xxx/xxx.ini 获取配置文件所有的section ['logging', 'mysql'] 获取指定section下所有option ['host', 'port', 'user', 'password'] 获取指定section下所有的键值对 [('host', '127.0.0.1'), ('port', '3306'), ('user', 'root'), ('password', '123456')] 获取指定的section下的option <class 'str'> 127.0.0.1
综合使用方法:
import configparser """ 读取配置文件信息 """ class ConfigParser(): config_dic = {} @classmethod def get_config(cls, sector, item): value = None try: value = cls.config_dic[sector][item] except KeyError: cf = configparser.ConfigParser() cf.read('settings.ini', encoding='utf8') #注意setting.ini配置文件的路径 value = cf.get(sector, item) cls.config_dic = value finally: return value if __name__ == '__main__': con = ConfigParser() res = con.get_config('logging', 'level') print(res