数据编码和处理
主要涉及用Python处理不同方式编码的数据,如CSV、JSON、XML和二进制包装记录。
读写CSV数据
使用csv
库。
import csv
with open('stocks.csv') as f:
f_csv = csv.reader(f)
headers = next(f_csv)
for row in f_csv:
# Process row
...
# row是每行的列表,其中的值通过下标访问
import csv
with open('stocks.csv') as f:
f_csv = csv.DictReader(f)
for row in f_csv:
# process row
...
# 通过字典方式读取,row是一个字典,可通过`row[name]`访问对应值
写入时要先创建一个writer
对象。
headers = ['Symbol','Price','Date','Time','Change','Volume']
rows = [('AA', 39.48, '6/11/2007', '9:36am', -0.18, 181800),
('AIG', 71.38, '6/11/2007', '9:36am', -0.15, 195500),
('AXP', 62.58, '6/11/2007', '9:36am', -0.46, 935000),
]
with open('stocks.csv','w') as f:
f_csv = csv.writer(f)
f_csv.writerow(headers)
f_csv.writerows(rows)
对于字典型数据写入,创建DictWriter
对象。
headers = ['Symbol', 'Price', 'Date', 'Time', 'Change', 'Volume']
rows = [{'Symbol':'AA', 'Price':39.48, 'Date':'6/11/2007',
'Time':'9:36am', 'Change':-0.18, 'Volume':181800},
{'Symbol':'AIG', 'Price': 71.38, 'Date':'6/11/2007',
'Time':'9:36am', 'Change':-0.15, 'Volume': 195500},
{'Symbol':'AXP', 'Price': 62.58, 'Date':'6/11/2007',
'Time':'9:36am', 'Change':-0.46, 'Volume': 935000},
]
with open('stocks.csv','w') as f:
f_csv = csv.DictWriter(f, headers)
f_csv.writeheader()
f_csv.writerows(rows)
读写JSON数据
json
模块提供了很简单的方式来编解码JSON数据。
import json
data = {
'name' : 'ACME',
'shares' : 100,
'price' : 542.23
}
json_str = json.dumps(data)
data = json.loads(json_str)
JSON编码支持基本数据类型None
、bool
、int
、float
、str
以及包含这些类型的list
、tuple
和dict
,对于dict
的keys必须是字串类型,并且应该只编码list
和dict
。
JSON编码对于Python字典,除了True变成true,False变成false,None变成null,没有区别了。
如果要让JSON数据更美观打印出来,使用pprint.pprint()
方法。
与关系型数据库进行交互
最好使用列表元组格式数据。
编解码Base64数据
base64
模块有两个函数b64encode()
和b64decode()
可以完成编解码。
>>> import base64
>>> s = b'hello'
>>> a = base64.b64encode(s)
>>> a
b'aGVsbG8='
>>> base64.b64decode(a)
b'hello'
>>>
base64只能处理字节字串或数组,如果要处理文本字串,需要增加一个编解码到字节码的过程。
读写二进制数组数据
使用struct
模块处理二进制数据。
from struct import Struct
def write_records(records, format, f):
'''
Write a sequence of tuples to a binary file of structures.
'''
record_struct = Struct(format)
for r in records:
f.write(record_struct.pack(*r))
# Example
if __name__ == '__main__':
records = [ (1, 2.3, 4.5),
(6, 7.8, 9.0),
(12, 13.4, 56.7) ]
with open('data.b', 'wb') as f:
write_records(records, '<idd', f)
以块形式读取文件。
from struct import Struct
def read_records(format, f):
record_struct = Struct(format)
chunks = iter(lambda: f.read(record_struct.size), b'')
return (record_struct.unpack(chunk) for chunk in chunks)
# Example
if __name__ == '__main__':
with open('data.b','rb') as f:
for rec in read_records('<idd', f):
# Process rec
...
一次性读取。
from struct import Struct
def unpack_records(format, data):
record_struct = Struct(format)
return (record_struct.unpack_from(data, offset)
for offset in range(0, len(data), record_struct.size))
# Example
if __name__ == '__main__':
with open('data.b', 'rb') as f:
data = f.read()
for rec in unpack_records('<idd', data):
# Process rec
...
结构体使用了一些结构码如i, d, f等,<
表示字节顺序低位在前。
结构体的size
属性包含结构的字节数,pack()
和unpack()
方法被用来打包和解包数据。