《Python从小白到大牛》第二部分-第一篇(数据交换格式)

#python高级使用库与框架

"""
数据交换格式:
CSV格式、XML格式和JSON格式

CSV格式:“同学”,“你好!\n今天上午...”,“KKZ”,“2012年12月08日”   #,隔开的是不同行
数据量增加后,会更加复杂,可能会搞乱它们的顺序。

XML和JSON格式可以自带描述信息,称为”自描述的“结构化文档:
XML格式:
<?xml version="1.0" encoding="UTF-8"?>
<note>
    <to>同学</to>
    <content>你好!\n今天下午...</content>
    <from>KKZ</from>
    <date>2012年12月08日</date>
</note>
<>中的内容就是描述数据的标识,在XML中称为”标签“。

JSON格式:
{to:"同学",content:"你好!\n今天上午...",from:"KKZ",date:"2012年12月08日"}
数据放在"{}"中,每个数据项之前都有一个描述名,描述名和数据项之间用冒号":"分开,JSON所用字节数要比XML少,因此也被称为”轻量级“数据交换格式

CSV是用逗号分割数据项(也称为字段)的数据交换格式,CSV主要应用于电子表格和数据库之间的数据交换。

在windows平台下默认字符集是GBK,如果要用Excel打开CSV文件且不乱码,CSV文件要保存为GBK字符集。

可以使用excel打开CSV文件,在python中使用open()函数和字符串的split()方法,就可以读取并解析CSV数据了。格式复杂的CSV数据使用split()方法分隔之后还要做很多处理
推荐方式:使用csv模块用来处理CSV数据
reader()函数
CSV模块提供两个对CSV数据进行读写的基本函数csv.reader()和csv.writer()
csv.reader(csvfile, dialect='excel', **fmtparams)
该函数返回一个读取器reader对象,csvfile参数是CSV文件对象,dialect参数是方言,方言提供了一组预定好的格式化参数,fmtparams参数可以提供单个格式化参数
csv.excel类定义Excel生成的CSV文件的常用属性,它的方言名称是‘excel’
csv.excel_tab类定义了Excel生成的Tab,分隔文件的常用属性,它的方言名称是‘excel_tab’
csv.unix_dialect定义了在UNIX系统上生成的CSV文件的常用属性,使用\n作为行终止符,而windows下使用'\r\n'作为行终止符,它的方言名称是unix

csv.writer(csvfile, dialect='excel', **fmtparams)
csv.writer()函数返回一个写入器writer对象,函数参数同csv.reader()函数

"""
# import csv
# with open('data/bool.csv', 'r', encoding='gbk') as rf:
#     reader = csv.reader(rf, dialect=csv.excel)
# #    for row in reader:
# #        print('|'.join(row))   #join函数,拼接字符串
# #读取器对象是一个可迭代对象
#     with open('data/books2.csv', 'w', newline='', encoding='gbk') as wf:
#         writer = csv.writer(wf, delimiter='\t')
#         for row in reader:
#             print('|'.join(row))
#             writer.writerow(row)
# #delimiter相当于分隔符

"""
XML数据交换格式
XML文档结构要遵守一定的格式规范。XML虽然在形式上与HTML很相似,但是有着严格的语法规则。
1.声明
<?xml version="1.0" encoding="UTF-8"?>
2.根元素
<note>是XML的根元素,根元素只有一个,开始标签和结束标签必须一致。
3.子元素
to、content、from等都是子元素,所
有子元素都要有结束标签,开始标签和结束标签要一致,如果两者间没有内容,可以使用<from/>,称为空标签
4.属性
属性定义在开始标签中,在开始标签中<Note id="1">,id="1"是Note元素的一个属性,id是属性名,1是属性值,其中属性值必须放置在双引号或者单引号中间,一个元素不能有多个相同名字的属性
5.命名空间
命名空间用于XML文档,提供名字唯一的元素和属性,两个相同的子元素放在同一命名空间中会造成名称冲突,但是将两个相同的子元素放在两个命名空间,就不会发生冲突
xmlns:开头的内容都属于命名空间
6.限定名
它是由命名空间引出的概念,定义了元素和属性的合法标识符,限定名通常在XML文档中用作特定元素或属性引用,图16-4中的标签<soap:Body>就是合法的限定名,前缀soap是由命名空间定义的
"""

"""
<?xml version="1.0" encoding="UTF-8"?>                                               #声明
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">                #
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"                                     #命名空间
    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body>                                                                      #限定名
        <queryResponse xmlns="http://tempuri.org/">
            <queryResult>
                <note>                                                               #<note id="1">  id属性
                    <UserID>string</UserID>
                    <CDate>string</CDate>
                    <Content>string</Content>
                    <ID>int</ID>
                </note>
                <note>
                    <UserID>string</UserID>
                    <CDate>string</CDate>
                    <Content>string</Content>
                    <ID>int</ID>
                </note>
            </queryResult>
        </queryResponse>
    </soap:Body>
</soap:Envelope>
"""

"""
解析XML文档
XML文档在目前由SAX和DOM两种流行的模式。
SAX:是一种基于事件驱动的解析模式。解析XML文档时,程序会从上到下读取XML文档,遇到开始标签、结束标签和属性等,就会触发相应的事件。但是这种解析XML文件的方式有一个弊端,
那就是只能读取XML文档,不能写入XML,但是优点是解析速度快。
DOM:将XML文档作为一棵树状结构进行分析,获取节点的内容以及相关属性,或是新增、删除和修改节点的内容。DOM模式将XML文件的元素视为一个树状结构的节点,一次性读入内存,如果文档较大
解析速度就会变慢。但是DOM模式有一个优点就是能够修改XML文档。

python中常用的解析方法:SAX、DOM以及兼顾两者优点的ElementTree模块,ElementTree就像一个轻量级的DOM,执行速度快,消耗内存少,是目前解析和生成XML的最好选择。

实际开发中,往往需要查找一些特殊的元素或者某些特殊的属性,这就需要用到find方法,同时结合XPath匹配查找
find(match, namespaces=None)
查找匹配的第一个子元素,match可以是标签名或者XPath,返回元素对象或None。namespaces指定命名空间,如果namespaces非空,那么查找会在指定的命名空间的标签中进行

findall(match, namespaces=None)
查找所有匹配的子元素,返回值是符合条件的元素列表

findtext(match, default=None, namespaces=None)
查找匹配的第一个子元素的文本,如果未找到元素则返回默认,default参数是默认值
XPath是专门用来在XML文档中查找信息的语言,XPath将XML中的所有元素、属性和文本都看作节点(Node),根元素就是根节点,没有父节点,属性称为属性节点,文本称为文本节点。
除了根节点,其他节点都有一个父节点,零或多个子节点和兄弟节点。
XPath表达式:
nodename  选择nodename子节点 
.         选择当前节点                    ./Note当前节点下的所有Note子节点
/         路径指示符,相当于目录分隔符       ./Note/CDate表示所有Note子节点下的CDate节点
..        选择父节点                      ./Note/CDate/..表示CDate节点的父节点,也就是Note节点
//        所有后代节点(包括子节点、孙节点等) .//CDate表示当前节点中查找所有CDate后代节点
[@attrib] 选择指定属性的所有节点             ./Note[@id]表示有id属性的所有Note节点
[@attrib='value']  选择指定属性等于value的所有节点  ./Note[@id='1']表示id属性等于‘1’的所有Note节点
[position] 指定位置,位置从1开始,最后一个可以使用last()获取    ./Note[1]表示第一个Note节点,./Note[last()]表示最后一个Note节点,
./Note[last()-1]表示倒数第二个Note节点

"""
import xml.etree.ElementTree as ET
tree = ET.parse('test.xml')   #通过parse函数创建xml树   返回一个文件对象
print(type(tree))         #类型   <class 'xml.etree.ElementTree.ElementTree'>

root = tree.getroot()     #获取根元素
print(type(root))         #类型   <class 'xml.etree.ElementTree.Element'>
print(root.tag)           #根标签<Notes>

for index, child in enumerate(root):            #序列号 子元素标签 属性
    print("第{0}个{1}元素,属性:{2}".format(index, child.tag, child.attrib))
    for i, child_child in enumerate(child):     #子元素中的子元素的标签以及内容
        print('标签:{0},内容:{1}'.format(child_child.tag, child_child.text))
print("")
print("XPath表达式:")
node = root.find("./Note")
print(node.tag, node.attrib)

node = root.find("./Note/CDate")
print(node.text)

node = root.find("./Note/CDate/..")
print(node.tag, node.attrib)

node = root.find(".//CDate")           #查找当前节点所有后代节点中第一个CDate节点
print(node.text)

node = root.find("./Note[@id]")        #查找当前节点下第一个具有id属性的Note节点
print(node.tag, node.attrib)

node = root.find("./Note[@id='2']")    #查找当前节点下属性id='2'的Note节点
print(node.tag, node.attrib)

node = root.find("./Note[2]")          #查找当前节点下第二个Note节点
print(node.tag, node.attrib)

node = root.find("./Note[last()]")     #查找当前节点下最后一个Note节点
print(node.tag, node.attrib)

node = root.find("./Note[last()-2]")   #查找倒数第三个Note节点
print(node.tag, node.attrib)

"""
JSON数据交换格式:
构成JSON文档的两种结构为对象和数组,对象是”名称:值“对集合,它类似与Python中Map类型,而数组是一串元素的集合
JSON对象是一个无序的”名称/值“对集合,一个对象以”{“ 开始 以”}“结束,每个名称后跟一个”:“,每个名称:值对间用‘,’隔开
”名称“是字符串类型,”值“可以是任何合法的JSON类型
{
    ”name“:"a.htm",
    "size":345,
    "saved":true
}
JSON数组是值的有序集合,以'['开始,以']'结束,值之间用”,“分隔。JSON数组的语法表示:
["text", "html", "css"]  在数组中,值可以是双引号括起来的字符串、数字、true、false、null、对象或者数组,而且这些结构可以嵌套

JSON数据编码:
在Python程序中要想将Python数据网络传输和存储,可以将Python数据转换为JSON数据再进行传输和存储,这个过程称为编码(encode)
Python提供的内置模块json可以帮助实现JSON的编码和解码,JSON编码使用dumps()和dump(),dumps()函数将编码结果以字符串形式返回,
dump()函数将编码结果保存到文件对象(类似文件对象或流)中。

"""
import json
py_dict = {'name':'tony', 'age':30, 'sex':True}
py_list = [1, 3]
py_tuple = ('A', 'B', 'C')

py_dict['a'] = py_list
py_dict['b'] = py_tuple

print(py_dict)
print(type(py_dict))

json_obj = json.dumps(py_dict)
print(json_obj)
print(type(json_obj))

json_obj = json.dumps(py_dict, indent=4)
print(json_obj)

with open('./data1.json', 'w') as f:
    json.dump(py_dict, f)

with open('./data2.json', 'w') as f:
    json.dump(py_dict, f, indent=4)

#解码
with open('./data2.json') as f:
    data = json.load(f)     #导入JSON文件
    print(data)
    print(type(data))
    print(data['name'])

"""
配置文件:windows平台经常使用一种ini文件(initialization File)它是windows系统配置文件所采用的存储格式,也称为配置文件。
配置文件采用键值对数据结构,可以进行少量的数据交换和存储。
;Startup节
[Startup]
RequireOS = windows 2000
RequireMSI = 3.0
RequuireIE = 6.0.2600.0

;Product节
[Product]
msi = AcroRead.msi

;windows 2000节
[windows 2000]
PlatformID = 2
;主版本号
MajorVersion = 5
ServicePackMajor = 4
其中包括节、配置项和注释。节中包含若干配置项,配置项由键值对构成,默认情况下键和值用等号进行分割。注释使用分号";",注释要独占一行。

读取配置文件
Python标准库中提供了对配置文件读写的模块-configparser。configparser模块中提供了一个配置解析器类ConfigParser,通过ConfigParser的相关方法可以实现对配置文件读写操作。

注意:如果文件中有中文(注释),则必须正确指定字符集,否则会有解析错误
"""
print('')
print('ini配置文件章节:')
import configparser
config = configparser.ConfigParser() #创建解析器对象

config.read('rdpwrap.ini', encoding='utf-8')   #读取并解析配置文件

print(config.sections())                       #返回所有的节

section1 = config['Main']                  #返回Main节
print(config.options('Main'))             #Main节中的各个配置项

print(section1['Updated'])            #返回Main节的Updated配置项中的内容
print(section1['LogFile'])

print(config['PatchCodes']['nop'])    #返回PatchCodes节的nop配置项中的内容

value = config.get('Main', 'Updated')  #获得Main节的Updated中的内容
print(type(value))                     #类型为字符串类型

value = config.getint('PatchCodes', 'nop')   #获得PatchCodes节中的nop配置项,并以整型读取信息
print(type(value))                    #类型为整型类型

#写入配置文件,包括更新节和配置项,以及添加节和配置项。
config['Main']['Updated'] = '2022-07-10a'

config['PatchCodes']['nop'] = '91'

# config.add_section('Section2')            #添加节
# config.set('Section2', 'name', 'Mac')     #为节添加配置项,添加的是一对配置项,‘name’ = 'Mac'

# with open('rdpwrap.ini', 'w') as fw:
#     config.write(fw)                      #将结果写入配置文件

print(config.sections())                       #返回所有的节

print(config.options('Section2'))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值