python教程10、模块之json,pickle,xml,pyyaml,shutil,configparser
序列化
Python中用于序列化的两个模块
- json 用于【字符串】和 【python基本数据类型】 间进行转换
- pickle 用于【python特有的类型】 和 【python基本数据类型】间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
pickle模块提供了四个功能:dumps、dump、loads、load
json模块
# json()将字符串形式的列表或字典转换为list或dict类型,json是所有语言相互通信的方式
# 注意外层字符形式一定是''单引号,'{"a":"xiao","b":"xiao"}'列表或字典中的字符串一定要""双引号,否则报错
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import json # json.dumps() 将python基本数据类型转化成字符串形式 dic = { 'k1' : 'v1' } print (dic, type (dic)) result = json.dumps(dic) print (result, type (result)) # json.loads() 将python字符串形式转化成基本数据类型 s = '{"k1":123}' dic = json.loads(s) print (dic, type (dic)) # json.dump() 先序列化,再写入文件 li = [ 11 , 22 , 33 ] json.dump(li, open ( 'db' , 'w' )) # json.load() 读取文件反序列化 l = json.load( open ( 'db' , 'r' )) print (l, type (l)) |
pickle模块
pickple只有python才能用,用于复杂类型的序列化,(如果是序列化一个对象,在别的模块中反序列化的时候一定要导入该对象所属的类,否则报错)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
import pickle # pickle.dumps() 序列化 li = [ 11 , 22 , 33 ] r = pickle.dumps(li) print (r) # pickle.loads() 反序列化 result = pickle.loads(r) print (result, type (result)) # pickle.dump() 先序列化,再写入文件 l1 = [ 11 , 22 , 33 , 55 ] pickle.dump(l1, open ( 'db' , 'wb' )) # pickle.load() 读取文件反序列化 result1 = pickle.load( open ( 'db' , 'rb' )) print (result1, type (result1)) |
XML模块
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过,古时候,在json还没诞生的黑暗年代,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml,XML文件格式如下:
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2023</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2026</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2026</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> </data>
1、解析XML两种方法
(1)利用ElementTree.XML将字符串解析成xml对象
1
2
3
4
5
6
7
|
from xml.etree import ElementTree as ET # 打开文件,读取XML内容 str_xml = open ( 'xo.xml' , 'r' ).read() # 将字符串解析成xml特殊对象,root代指xml文件的根节点 root = ET.XML(str_xml) |
(2)利用ElementTree.parse将文件直接解析成xml对象
1
2
3
4
5
6
7
|
from xml.etree import ElementTree as ET # 直接解析xml文件 tree = ET.parse( "xo.xml" ) # 获取xml文件的根节点 root = tree.getroot() |
2、操作XML
XML格式类型是节点嵌套节点,对于每一个节点均有以下功能,以便对当前节点进行操作:

由于 每个节点 都具有以上的方法,并且在上一步骤中解析时均得到了root(xml文件的根节点),so 可以利用以上方法进行操作xml文件。
(1)遍历XML文档的所有内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
from xml.etree import ElementTree as ET ############ 解析方式一 ############ """ # 打开文件,读取XML内容 str_xml = open('xo.xml', 'r').read() # 将字符串解析成xml特殊对象,root代指xml文件的根节点 root = ET.XML(str_xml) """ ############ 解析方式二 ############ # 直接解析xml文件 tree = ET.parse( "xo.xml" ) # 获取xml文件的根节点 root = tree.getroot() ### 操作 # 顶层标签 print (root.tag) # 遍历XML文档的第二层 for child in root: # 第二层节点的标签名称和标签属性 print (child.tag, child.attrib) # 遍历XML文档的第三层 for i in child: # 第二层节点的标签名称和内容 print (i.tag,i.text) |
(2)遍历XML中指定的节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
from xml.etree import ElementTree as ET ############ 解析方式一 ############ """ # 打开文件,读取XML内容 str_xml = open('xo.xml', 'r').read() # 将字符串解析成xml特殊对象,root代指xml文件的根节点 root = ET.XML(str_xml) """ ############ 解析方式二 ############ # 直接解析xml文件 tree = ET.parse( "xo.xml" ) # 获取xml文件的根节点 root = tree.getroot() ### 操作 # 顶层标签 print (root.tag) # 遍历XML中所有的year节点 for node in root. iter ( 'year' ): # 节点的标签名称和内容 print (node.tag, node.text) |
(3)修改节点内容
由于修改的节点时,均是在内存中进行,其不会影响文件中的内容。所以,如果想要修改,则需要重新将内存中的内容写到文件。
解析字符串方式,修改,保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
from xml.etree import ElementTree as ET ############ 解析方式一 ############ # 打开文件,读取XML内容 str_xml = open ( 'xo.xml' , 'r' ).read() # 将字符串解析成xml特殊对象,root代指xml文件的根节点 root = ET.XML(str_xml) ############ 操作 ############ # 顶层标签 print (root.tag) # 循环所有的year节点 for node in root. iter ( 'year' ): # 将year节点中的内容自增一 new_year = int (node.text) + 1 node.text = str (new_year) # 设置属性 node. set ( 'name' , 'alex' ) node. set ( 'age' , '18' ) # 删除属性 del node.attrib[ 'name' ] ############ 保存文件 ############ tree = ET.ElementTree(root) tree.write( "newnew.xml" , encoding = 'utf-8' ) |
解析文件方式,修改,保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
from xml.etree import ElementTree as ET ############ 解析方式二 ############ # 直接解析xml文件 tree = ET.parse( "xo.xml" ) # 获取xml文件的根节点 root = tree.getroot() ############ 操作 ############ # 顶层标签 print (root.tag) # 循环所有的year节点 for node in root. iter ( 'year' ): # 将year节点中的内容自增一 new_year = int (node.text) + 1 node.text = str (new_year) # 设置属性 node. set ( 'name' , 'alex' ) node. set ( 'age' , '18' ) # 删除属性 del node.attrib[ 'name' ] ############ 保存文件 ############ tree.write( "newnew.xml" , encoding = 'utf-8' ) 解析文件方式,修改,保存 |
(4)删除节点
解析字符串方式打开,删除,保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
from xml.etree import ElementTree as ET ############ 解析字符串方式打开 ############ # 打开文件,读取XML内容 str_xml = open ( 'xo.xml' , 'r' ).read() # 将字符串解析成xml特殊对象,root代指xml文件的根节点 root = ET.XML(str_xml) ############ 操作 ############ # 顶层标签 print (root.tag) # 遍历data下的所有country节点 for country in root.findall( 'country' ): # 获取每一个country节点下rank节点的内容 rank = int (country.find( 'rank' ).text) if rank > 50 : # 删除指定country节点 root.remove(country) ############ 保存文件 ############ tree = ET.ElementTree(root) tree.write( "newnew.xml" , encoding = 'utf-8' ) |
解析文件方式打开,删除,保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
from xml.etree import ElementTree as ET ############ 解析文件方式 ############ # 直接解析xml文件 tree = ET.parse( "xo.xml" ) # 获取xml文件的根节点 root = tree.getroot() ############ 操作 ############ # 顶层标签 print (root.tag) # 遍历data下的所有country节点 for country in root.findall( 'country' ): # 获取每一个country节点下rank节点的内容 rank = int (country.find( 'rank' ).text) if rank > 50 : # 删除指定country节点 root.remove(country) ############ 保存文件 ############ tree.write( "newnew.xml" , encoding = 'utf-8' ) |
3、创建XML文档
创建方式(一)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
from xml.etree import ElementTree as ET # 创建根节点 root = ET.Element( "famliy" ) # 创建节点大儿子 son1 = ET.Element( 'son' , { 'name' : '儿1' }) # 创建小儿子 son2 = ET.Element( 'son' , { "name" : '儿2' }) # 在大儿子中创建两个孙子 grandson1 = ET.Element( 'grandson' , { 'name' : '儿11' }) grandson2 = ET.Element( 'grandson' , { 'name' : '儿12' }) son1.append(grandson1) son1.append(grandson2) # 把儿子添加到根节点中 root.append(son1) root.append(son1) tree = ET.ElementTree(root) tree.write( 'oooo.xml' ,encoding = 'utf-8' , short_empty_elements = False ) |
创建方式(一)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
from xml.etree import ElementTree as ET # 创建根节点 root = ET.Element( "famliy" ) # 创建大儿子 # son1 = ET.Element('son', {'name': '儿1'}) son1 = root.makeelement( 'son' , { 'name' : '儿1' }) # 创建小儿子 # son2 = ET.Element('son', {"name": '儿2'}) son2 = root.makeelement( 'son' , { "name" : '儿2' }) # 在大儿子中创建两个孙子 # grandson1 = ET.Element('grandson', {'name': '儿11'}) grandson1 = son1.makeelement( 'grandson' , { 'name' : '儿11' }) # grandson2 = ET.Element('grandson', {'name': '儿12'}) grandson2 = son1.makeelement( 'grandson' , { 'name' : '儿12' }) son1.append(grandson1) son1.append(grandson2) # 把儿子添加到根节点中 root.append(son1) root.append(son1) tree = ET.ElementTree(root) tree.write( 'oooo.xml' ,encoding = 'utf-8' , short_empty_elements = False ) |
创建方式(一)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
from xml.etree import ElementTree as ET # 创建根节点 root = ET.Element( "famliy" ) # 创建节点大儿子 son1 = ET.SubElement(root, "son" , attrib = { 'name' : '儿1' }) # 创建小儿子 son2 = ET.SubElement(root, "son" , attrib = { "name" : "儿2" }) # 在大儿子中创建一个孙子 grandson1 = ET.SubElement(son1, "age" , attrib = { 'name' : '儿11' }) grandson1.text = '孙子' et = ET.ElementTree(root) #生成文档对象 et.write( "test.xml" , encoding = "utf-8" , xml_declaration = True , short_empty_elements = False ) |
由于原生保存的XML时默认无缩进,如果想要设置缩进的话, 需要修改保存方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
from xml.etree import ElementTree as ET from xml.dom import minidom def prettify(elem): """将节点转换成字符串,并添加缩进。 """ rough_string = ET.tostring(elem, 'utf-8' ) reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent = "\t" ) # 创建根节点 root = ET.Element( "famliy" ) # 创建大儿子 # son1 = ET.Element('son', {'name': '儿1'}) son1 = root.makeelement( 'son' , { 'name' : '儿1' }) # 创建小儿子 # son2 = ET.Element('son', {"name": '儿2'}) son2 = root.makeelement( 'son' , { "name" : '儿2' }) # 在大儿子中创建两个孙子 # grandson1 = ET.Element('grandson', {'name': '儿11'}) grandson1 = son1.makeelement( 'grandson' , { 'name' : '儿11' }) # grandson2 = ET.Element('grandson', {'name': '儿12'}) grandson2 = son1.makeelement( 'grandson' , { 'name' : '儿12' }) son1.append(grandson1) son1.append(grandson2) # 把儿子添加到根节点中 root.append(son1) root.append(son1) raw_str = prettify(root) f = open ( "xxxoo.xml" , 'w' ,encoding = 'utf-8' ) f.write(raw_str) f.close() |
4、命名空间
详细介绍,猛击这里
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
from xml.etree import ElementTree as ET ET.register_namespace( 'com' , "http://www.company.com" ) #some name # build a tree structure root = ET.Element( "{http://www.company.com}STUFF" ) body = ET.SubElement(root, "{http://www.company.com}MORE_STUFF" , attrib = { "{http://www.company.com}hhh" : "123" }) body.text = "STUFF EVERYWHERE!" # wrap it in an ElementTree instance, and save as XML tree = ET.ElementTree(root) tree.write( "page.xml" , xml_declaration = True , encoding = 'utf-8' , method = "xml" ) |
PyYAML模块
Python也可以很容易的处理ymal文档格式,只不过需要安装一个模块,参考文档:http://pyyaml.org/wiki/PyYAMLDocumentation
configparser模块
configparser用于处理特定格式的文件如有键值对[]等,其本质上是利用open来操作文件。
1
2
3
4
5
6
7
8
9
|
# 注释1 ; 注释 2 [section1] # 节点 k1 = v1 # 值 k2:v2 # 值 [section2] # 节点 k1 = v1 # 值 |
1、获取所有节点
1
2
3
4
5
6
|
import configparser config = configparser.ConfigParser() config.read( 'xxxooo' , encoding = 'utf-8' ) ret = config.sections() print (ret) |
2、获取指定节点下所有的键值对
1
2
3
4
5
6
|
import configparser config = configparser.ConfigParser() config.read( 'xxxooo' , encoding = 'utf-8' ) ret = config.items( 'section1' ) print (ret) |
3、获取指定节点下所有的建
1
2
3
4
5
6
|
import configparser config = configparser.ConfigParser() config.read( 'xxxooo' , encoding = 'utf-8' ) ret = config.options( 'section1' ) print (ret) |
4、获取指定节点下指定key的值
1
2
3
4
5
6
7
8
9
10
11
12
|
import configparser config = configparser.ConfigParser() config.read( 'xxxooo' , encoding = 'utf-8' ) v = config.get( 'section1' , 'k1' ) # v = config.getint('section1', 'k1') # v = config.getfloat('section1', 'k1') # v = config.getboolean('section1', 'k1') print (v) |
5、检查、删除、添加节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import configparser config = configparser.ConfigParser() config.read( 'xxxooo' , encoding = 'utf-8' ) # 检查 has_sec = config.has_section( 'section1' ) print (has_sec) # 添加节点 config.add_section( "SEC_1" ) config.write( open ( 'xxxooo' , 'w' )) # 删除节点 config.remove_section( "SEC_1" ) config.write( open ( 'xxxooo' , 'w' )) |
6、检查、删除、设置指定组内的键值对
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
import configparser config = configparser.ConfigParser() config.read( 'xxxooo' , encoding = 'utf-8' ) # 检查 has_opt = config.has_option( 'section1' , 'k1' ) print (has_opt) # 删除 config.remove_option( 'section1' , 'k1' ) config.write( open ( 'xxxooo' , 'w' )) # 设置 config. set ( 'section1' , 'k10' , "123" ) config.write( open ( 'xxxooo' , 'w' )) |
shutil模块
高级的 文件、文件夹、压缩包 处理模块,注意当前用户要是对其他文件或目录没有权限会报错
shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中
1
2
3
|
import shutil shutil.copyfileobj( open ( '/etc/passwd' , 'r' ), open ( 'password' , 'w' )) |
shutil.copyfile(src, dst) 拷贝文件
1
2
3
|
import shutil shutil.copyfile( '/etc/passwd' , 'password1' ) |
shutil.ignore_patterns(*patterns) 忽略某些文件
shutil.copytree(src, dst, symlinks=False, ignore=None) 递归的去拷贝文件夹
1
2
3
|
import shutil shutil.copytree( '/etc' , 'etc' , ignore = shutil.ignore_patterns( '*.conf' , 'tmp*' )) |
shutil.rmtree(path[, ignore_errors[, onerror]]) 递归删除文件夹
1
2
3
|
import shutil shutil.rmtree( 'etc' ) |
shutil.move(src, dst) 它类似mv命令,其实就是重命名。
1
2
3
|
import shutil shutil.move( 'folder1' , 'folder3' ) |
shutil.make_archive(base_name, format,...) 创建压缩包并返回文件路径,例如:zip、tar
创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/ - format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
1
2
3
4
5
6
7
|
import shutil #将 /home/tomcat/ 下的文件打包放置当前程序目录 ret = shutil.make_archive( "test" , 'gztar' , root_dir = '/home/tomcat/' ) #将 /home/tomcat/ 下的文件打包放置 /home/tomcat/目录 ret = shutil.make_archive( "/home/tomcat/www" , 'gztar' , root_dir = '/home/tomcat/' ) |
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
1
2
3
4
5
6
7
8
9
10
11
12
|
import zipfile # 压缩 z = zipfile.ZipFile( 'laxi.zip' , 'w' ) z.write( 'a.log' ) z.write( 'data.data' ) z.close() # 解压 z = zipfile.ZipFile( 'laxi.zip' , 'r' ) z.extractall() z.close() |
TarFile
1
2
3
4
5
6
7
8
9
10
11
12
|
import tarfile # 压缩 tar = tarfile. open ( 'your.tar' , 'w' ) tar.add( '/Users/wupeiqi/PycharmProjects/bbs2.log' , arcname = 'bbs2.log' ) tar.add( '/Users/wupeiqi/PycharmProjects/cmdb.log' , arcname = 'cmdb.log' ) tar.close() # 解压 tar = tarfile. open ( 'your.tar' , 'r' ) tar.extractall() # 可设置解压地址 tar.close() |