1.读写CSV文件
csv是类似xls的excel表格形式。
演示数据
csv数据读取
import csv
def rw_csv():
with open('test.csv') as f:
f_csv = csv.reader(f)
headers = next(f_csv)
for row in f_csv:
print(row)
# headers= ['姓名', '年龄', '性别']
# ['小明', '20', '男']
['小花', '21', '女']
['小华', '20', '男']
['小红', '19', '女']
这样获取数据只能通过取下标的方式,可以使用namedtuple来访问特定的字段读取数据
with open('test.csv') as f:
f_csv = csv.reader(f)
headers = next(f_csv)
Row = namedtuple('Row', headers)
for row in f_csv:
row = Row(*row)
print(row.姓名)
如果使用中文名,虽然可以读取数据,但是显得很奇怪,而且由于可能携带一些特殊字符,而出现意想不到的错误。
将数据转为字典
def rw_csv():
with open('test.csv') as f:
f_csv = csv.DictReader(f) # 将数据读取为OrderedDict对象
for row in f_csv:
print(row.get('姓名'), row.get('性别'))
写入csv数据
使用csv模块创建csv文件时,总是会出现空行的情况,解决这个问题,需要在open()中设置newline=''即可。
def rw_csv():
headers = ['姓名', '年龄', '性别']
# 数据格式为元组
rows = [('小明', 20, '男'), ('小红', 20, '男'), ('小花', 19, '女')]
with open('test2.csv', 'w', newline='') as f:
f_csv = csv.writer(f)
f_csv.writerow(headers)
f_csv.writerows(rows)
# 数据格式为字典
dic_rows = [{"姓名": '小明', '年龄': 20, '性别': '男'},
{"姓名": '小红', '年龄': 20, '性别': '男'},
{"姓名": '小花', '年龄': 19, '性别': '女'}]
with open('test3.csv', 'w', newline='') as f:
f_csv2 = csv.DictWriter(f, headers)
f_csv2.writeheader()
f_csv2.writerows(dic_rows)
2.json数据序列及反序列
loads,dumps这些方法不写了。
json解码时会从提供的数据中创建列表或字典,如果想创建其他对象,可以使用loads()提供的object_parirs_hook或者object_hook参数。如反序列化为有序字典(OrderDict),保持数据顺序不变。
>>> s = '{"name": "小花", "age": 15}'
>>> data = json.loads(s, object_pairs_hook=OrderedDict)
>>> data
OrderedDict([('name', '小花'), ('age', 15)])
区别是,object_pairs_hook 的传入参数是有序的键值对表,而 object_hook 是无序的dict。并且两个参数都给的话,object_pairs_hook 的优先级要更高。
loads可选参数:
ensure_ascii
dumps()可选参数:
indent,可以让格式更利于人辨识。
sort_keys,可以对键进行排序。默认False
ensure_ascii,当json数据中有中文时,中文往往会被编码为unicode,如果你不希望如此,可以设置成False,默认True
其他参数说明:点击链接
3.解析Xml文档
使用xml.etree.ElementTree模块可以从简单的xml文档中提供数据。
from xml.etree.ElementTree import parse
由于解析xml的方式我常用lxml解析,因此不过多说明
4.将字典转为XML
def dict_to_xml(tag, d):
"""字典转xml"""
ele = Element(tag)
for key, val in d.items():
child = Element(key)
child.text = str(val)
ele.append(child)
return ele
dic = {"name": "小明", "age": 15, "hobby": "read"}
from xml.etree.ElementTree import tostring
e = dict_to_xml('student', dic)
print(tostring(e))
# b'<student><name>小明</name><age>15</age><hobby>read</hobby></student>'
# 附加属性
e.set('_id', 'aabc')
print(tostring(e))
# b'<student _id="aabc"><name>小明</name><age>15</age><hobby>read</hobby></student>'
5.解析、修改和重写XML
存在一个xml文件pred.xml,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<stop>
<id>14791</id>
<nm>Clark</nm>
<sri>
<rt>22</rt>
<d>North</d>
<dd>North</dd>
</sri>
<cr>22</cr>
<pre>
<pt>5 Min</pt>
<fd>Howard</fd>
<v>1378</v>
<rn>22</rn>
</pre>
<pre>
<pt>15 Min</pt>
<fd>Howard</fd>
<v>1878</v>
<rn>22</rn>
</pre>
</stop>
修改xml文件
doc = parse('pred.xml')
root = doc.getroot()
print(root)
# 删除节点
root.remove(root.find('sri'))
root.remove(root.find('cr'))
root.getchildren().index(root.find('nm')) # 插入新节点
e = Element('spam')
e.text = 'This is a test'
root.insert(2, e)
doc.write('new_pred.xml', xml_declaration=True)
更新后的xml文件:
<?xml version='1.0' encoding='us-ascii'?>
<stop>
<id>14791</id>
<nm>Clark</nm>
<spam>This is a test</spam>
<pre>
<pt>5 Min</pt>
<fd>Howard</fd>
<v>1378</v>
<rn>22</rn>
</pre>
<pre>
<pt>15 Min</pt>
<fd>Howard</fd>
<v>1878</v>
<rn>22</rn>
</pre>
</stop>
6.与关系型数据库进行交互
关系型数据库,如mysql,sqlite等
交互的固定套路:
先连接数据库,在创建游标(cursor),在编写操作语句。
以sqlite数据库为例:
def conn_database():
conn = sqlite3.connect('test.db') # 连接数据库
currsor = conn.cursor() # 创建游标
currsor.execute('create table portfolio (symbol text, shares integer, price real)') # 编写sql语句,创建1个数据库
conn.commit() # 提交
currsor.execute('insert into portfolio values ("Good2", 90, 30.1)') # 插入数据
conn.commit()
data = currsor.execute('select * from portfolio')
print(list(data)) # [('Good', 100, 400.1), ('Good2', 90, 30.1)]
7.编码和解码十六进制数字
需要将十六进制组成的字符串解码为字节流,或将字节流编码为十六进制数
编解码十六进制数组成的原始字符串,可以使用binasii模块和base64模块。
>>> s = b'hello'
>>> import binascii
>>> h = binascii.b2a_hex(s)
>>> h
b'68656c6c6f'
>>> binascii.a2b_hex(h)
b'hello'
>>> import base64
>>> h = base64.b16encode(s)
>>> h
b'68656C6C6F'
>>> base64.b16decode(h)
b'hello'
8.base64编解码
编码b64encode(),解码b64decode()
>>> s = b'hello'
>>> a = base64.b64encode(s)
>>> a
b'aGVsbG8='
>>> b = base64.b64decode(a)
>>> b
b'hello'
9.读写二进制结构的数组
将数据编码为统一结构的二进制数组,在将数据读写到元组中。
将一列数组写入到二进制文件中。
def write_records(records, format, f):
import struct
record_struct = struct.Struct(format)
for r in records:
f.write(record_struct.pack(*r))
records = [(1, 2.3, 4.5), (6, 7.8, 9.0), (12, 13.4, 56.7)]
with open('data.txt', 'wb') as f:
write_records(records, '<idd', f)
将文件中的数据转为数组
方法1:按块以增量式的方式读取文件
def read_records(format, f):
record_struct = struct.Struct(format)
chunks = iter(lambda: f.read(record_struct.size), b'')
return (record_struct.unpack(chunk) for chunk in chunks)
if __name__ == '__main__':
with open('data.txt', 'rb') as f:
for rec read_records('<idd', f):
pass
方法2:使用read()调用将文件全部读取到一个字符串,然后一块块转换
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))
if __name__ == '__main__':
with open('data.txt', 'rb') as f:
data = f.read()
for rec in unpack_records('<idd', data):
pass
对于struct()模块的详解可以看下:
这篇文章
python官方文档
评论列表
已有0条评论