结构化的文本文件
结构化的文本有很多格式,区别它们的方法如下: 分隔符, 比如tab(‘\t’)、逗号(‘,’)或竖线(‘|’)。 如:逗号分隔值(csv) ‘<’和’>’标签, 如XML 和 HTML 标点符号, 如 JavaScript Object Notation (JSON)。 缩进 如:YAML (即:YAML Ain’t Markup Language的缩写) 混合的,例如各种配置文件
CSV
带分隔符的文件一般用作数据交换格式或数据库。
>>> import csv
>>> villains = [
['Doctor','No'],
['Rosa','klebb'],
['Mister','Big'],
['Auric','Goldfinger'],
['Ernst','Blofeld'],]
>>> with open('villains','wt') as fout: # 一个上下文管理器
csvout = csv.writer(fout)
csvout.writerows(villains)
>>> villains
[['Doctor', 'No'], ['Rosa', 'klebb'], ['Mister', 'Big'], ['Auric', 'Goldfinger'], ['Ernst', 'Blofeld']]
XML
带分隔符的文件仅有两维的数据:行和列,XML是最突出的处理这种转换的标记(markup)格式,它使用标签(tag)分隔数据。
XML通常用于数据传送和消息,它存在一些格式如:RSS和Atom,工业界有许多定制化的XML格式,例如:金融领域(http://www.service-architecture.com/articles/xml/finance_xml.html)
示例文件:menu.xml
在Python中解析XML最简单的方法是使用ElementTree,下面的代码用来解析menu.xml文件以及输出一些标签和属性:
>>> import xml.etree.ElementTree as et
>>> tree = et.ElementTree(file = ‘menu.xml’)
>>> root = tree.getroot()
>>> root.tag
‘menu’
>>> for child in root:
print('tag:',child.tag,'attributes:',child.attrib)
for grandchild in child:
print('\tag:',grandchild.tag,'attributes:',grandchild.attrib)
tag: breakfast attributes: {'hours': '7-11'}
ag: item attributes: {'price': '$6.00'}
ag: item attributes: {'price': '$4.00'}
tag: lunch attributes: {'hours': '11-3'}
ag: item attributes: {'price': '$5.00'}
tag: dinner attributes: {'hours': '3-10'}
ag: item attributes: {'price': '8.00'}
>>> len(root) #菜单选择的数目
3
>>> len(root[0]) #早餐项的数目
2
对于嵌套列表中的每一个元素,tag是标签字符串,attrib是它属性的一个字典。ElementTree有许多查找XML导出数据、修改数据乃至写入XML文件的方法,他的文档(https://docs.python.org/3.3/library/xml.etree.elementtree.html)中有详细介绍。
其他标准的Python XML库如下: xml.dom :JavaScript开发者比较熟悉的文档对象模型(DOM),将Web文档表示成层次结构,它会把整个XML文件载入到内存中,同样允许你获取所有的内容。
xml.sax : 简单的XML API 或者SAX都是通过在线解析XML,不需要一次载入所有内容到内存中,因此对于处理巨大的XML文件流是一个很好的选择。
HTML
更多用HTML来格式化输出显示结果而不是用于交换数据
JSON
JavaScript Object Notation(JSON,http://www.json.org)是源于JavaScript的当今很流行的数据交换格式,它是JavaScript语言的一个子集,也是Python合法可支持的语法。 Python只有一个主要的JSON模块json。
实例:以之前XML例子构件JSON的数据结构,再把JSON字符串解码成数据。
>>> menu = \
{
"breakfast":{
"hours":"7-11",
"items":{
"breakfast burritos":"$6.00",
"pancakes":"$4.00"
}
},
"lunch":{
"hours":"11-3",
"items":{
"hamburger":"$5.00"
}
},
"dinner":{
"hours":"3-10",
"items":{
"spaghetti":"$8.00"
}
}
}
>>>
使用dumps()将menu编码成JSON字符串
>>> import json
>>> menu_json = json.dumps(menu)
>>> menu_json
'{"breakfast": {"hours": "7-11", "items": {"breakfast burritos": "$6.00", "pancakes": "$4.00"}}, "lunch": {"hours": "11-3", "items": {"hamburger": "$5.00"}}, "dinner": {"hours": "3-10", "items": {"spaghetti": "$8.00"}}}'
>>>
使用load()把JSON字符串menu_json解析成Python的数据结构
>>> menu2 = json.loads(menu_json)
>>> menu2
{'breakfast': {'hours': '7-11', 'items': {'breakfast burritos': '$6.00', 'pancakes': '$4.00'}}, 'lunch': {'hours': '11-3', 'items': {'hamburger': '$5.00'}}, 'dinner': {'hours': '3-10', 'items': {'spaghetti': '$8.00'}}}
>>>
menu和menu2是具有相同键值的字典
YAML
yaml同样有键和值,但主要用来处理日期和时间,标准的Python库没有处理YAML的模块,因此需要安装第三方yaml操作数据,load()将YAML字符串转换为Python数据结构,而dump()正好相反。
配置文件
使用标准configparser模块处理Windows风格的初始化.ini文件,这些文件都包含key=value的定义,修改等自定义操作也可实现,请参阅configparser(https://docs.python.org/3.3/library/configparser.html).如果需要两层以上的嵌套结构,使用YAML或者JSON。
下面是一个简单的配置文件settings.cfg例子:
[english]
greeting = Hell
[french]
greeting = Bonjour
[files]
home = /usr/local
简单的插入:
bin = %(home)s/bin
>>>
>>> import configparser
>>> cfg = configparser.ConfigParser()
>>> cfg.read('settings.cfg')
['settings.cfg']
>>> cfg
>>> cfg['french']
>>> cfg['french']['greeting']
'Bonjour'
>>> cfg['files']['bin']
'/usr/local/bin'
>>>
其他交换格式
以下的二进制数据交换格式通常比XML或者JSON更加快速和复杂:
MsgPack(http://msgpack.org)
Protocol Buffers(https://code.google.com/p/protobuf/)
Avro(http://avro.apache.org/docs/current/)
Thrift(http://thrift.apache.org/)
使用pickle序列化
存储数据结构到一个文件中也称为序列化(serializing).Python提供了pickle模块以特殊的二进制格式保存和恢复数据对象。使用函数dump()序列化数据岛文件,而函数load()用作反序列化。
>>>
>>> import pickle
>>> import datetime
>>>
>>> now1 = datetime.datetime.utcnow()
>>> pickled = pickle.dumps(now1)
>>> now2 = pickle.loads(pickled)
>>> now1
datetime.datetime(2017, 3, 25, 3, 16, 49, 282762)
>>> now2
datetime.datetime(2017, 3, 25, 3, 16, 49, 282762)
>>>