数据编码处理

Python 2020-07-03 1309

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>&#23567;&#26126;</name><age>15</age><hobby>read</hobby></student>'  
# 附加属性  
e.set('_id', 'aabc')  
print(tostring(e))  
# b'<student _id="aabc"><name>&#23567;&#26126;</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官方文档

标签:Python
上一篇 操作DOM
下一篇 文件和IO

文章评论

评论列表

已有0条评论