机器学习-python语言基础第十天

对象持久化

扁平文件

格式话文本文件代码:

def write_scores():
    with open('data_list.txt', 'w', encoding='utf8') as f:
        f.write(str(scores))


def read_scores():
    with open('data_list.txt', 'r', encoding='utf8') as f:
        lst = eval(f.read())

    lst[0] = 99
    print(lst)


if __name__ == '__main__':
    write_scores()
    read_scores()

上述代码中,将一个数据类型写入到文件中,只能通过字符串的写入,如果读取时,利用list将字符串还原,它会将真个字符串每个字符一次还原,包括[,因此可以使用py的内置函数eval,将str堪称py表达式运行。
但这种方式对于传不同类型的参数比较麻烦,在为止的前提下无法区分数据。

pickle模块

person = {'name': 'Tom', 'age': 20}
s = pickle.dumps(person)
print(s)
p = pickle.loads(s)
print(p)
pickle.dump(person, open('pickle_db', 'wb'))
p = pickle.load(open('pickle_db', 'rb'))
print(p)

dumps序列化生成二进制字节类型,写入文件时,要使用wb,loads也是反序列化字节类型数据,dump和load时可以直接写入文件和在文件中加载。
pickle模块的方法,针对每一个数据类型的对象,只能写入一个文件,不可以在一个文件里写入多个类型的对象,如果向一次写入多个,可以借助字典表。

shelve模块

import shelve

scores = [99, 88, 77]
student = {'name': 'Mike', 'age': 20}
db = shelve.open('shelve_student')
db['s'] = student
db['scores'] = scores
print(len(db))

temp_student = db['s']
print(temp_student)
type(temp_student)

del db['scores']
print(len(db))
db.close()

shelve模块可以利用字典键值的原理来存储各种数据类型,有效的解决了其他序列化方式的不足,在利用shelve打开文件,获得一个对象后,需要在不使用时将其关闭。
同样的,shelve也可以将一个类的对象序列化:

import shelve


class Student:
    def __init__(self, name='', age=0):
        self.name = name
        self.age = age

    def __str__(self):
        return self.name


def write_shelve():
    s = Student('Tom', 20)
    db = shelve.open('shelve_student_db')
    db['s'] = s
    db.close()


def raad_shelve():
    db = shelve.open('shelve_student_db')
    st = db['s']
    print(st)
    print(st.name)
    db.close()


if __name__ == '__main__':
    write_shelve()
    raad_shelve()

字符串

概述

类型有:字符串str、字节bytes(不可变)、字节数组bytearray(可变)
字符编码架构:

  • 字符集:赋值一个编码到内存中,以便在内存中表示(Unicode就是典型的字符集标准)
  • 编码Encoding:转换字符到原始编码(ASCII、UTF8都是典型的编码规则)
  • 解码 Decoding:依据编码名称转换原始字节到字符的过程

字符串存储时,编码只作用于文件存储或中间媒介转换时,内存中总是存储解码以后的文本。

字符编码

常用的ASCII编码,存储在一个byte 0-127,只有128个字符,latin-1编码,存储在存储在一个Byte 128-255,而UTF-8的编码方式,不仅兼容了ASCII,同时还是一个可变长的,0-127代码点使用单字节、128-207代码点使用双字节、大于2047的使用3-4byte。注:这里说的代码点是以常用的unicode为基础的。

>>> ord('A')
65
>>> chr(68)
'D'
>>> chr(223)
'ß'
>>> chr(202)
'Ê'
>>> ord('优')
20248
>>> s1 = 'ABCD'
>>> s1.encode('ASCII')
b'ABCD'
>>> s2 = '优品课堂'
>>> type(s2)
<class 'str'>
>>> s2.encode('ASCII')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-3: ordinal not in range(128)
>>> s2.encode('UTF-8')
b'\xe4\xbc\x98\xe5\x93\x81\xe8\xaf\xbe\xe5\xa0\x82'
>>> b1=b'\xe4\xbc\x98\xe5\x93\x81\xe8\xaf\xbe\xe5\xa0\x82'
>>> b1.decode('UTF-8')
'优品课堂'
>>> b1.decode('utf-16')
'볤\ue598膓꿨\ue5be芠'
>>> s1.encode('UTF-8')
b'ABCD'
>>> s1.encode()
b'ABCD'

可以使用内置函数ord来获取一个字符的代码点,也可以格局一个代码点使用chr函数获取字符。
str.encode(‘编码’),是将特定的字符串,按照制定的编码方式编码,bytes.decoding('编码‘)是将字节类型,解码成字符串。s2使用ASCII编码时出错,时因为ASCII不支持中文的字符,因此无法编码。如果参数不写,则使用默认的编码方式。py的默认编码方式是utf8。

>>> import sys
>>> sys.getdefaultencoding()
'utf-8'

文件的写入也可以制定编码方式,如果不写,则默认的是gbk方式:

>>> open('date.txt','w',encoding='utf-8').write('优品课堂')
4
>>> open('date.txt','r',encoding='utf-8').read()
'优品课堂'
>>> open('date2.txt','w').write('优品课堂')
4
>>> 
>>> open('date2.txt','r',encoding='gbk').read()
'优品课堂'

类型转换

>>> s = 'abc'
>>> s1='优品课堂'
>>> s.encode()
b'abc'
>>> s1.encode()
b'\xe4\xbc\x98\xe5\x93\x81\xe8\xaf\xbe\xe5\xa0\x82'
>>> open('date.txt','r',encoding='utf-8').read()
'优品课堂'
>>> open('date.txt','rb').read()
b'\xe4\xbc\x98\xe5\x93\x81\xe8\xaf\xbe\xe5\xa0\x82'
>>> bytes('abc','ascii')
b'abc'
>>> bytes('优品课堂','utf-8')
b'\xe4\xbc\x98\xe5\x93\x81\xe8\xaf\xbe\xe5\xa0\x82'
>>> bytes([87,65,89,87])
b'WAYW'
>>> b=b'abc'
>>> type(b)
<class 'bytes'>

bytes类型可以通过一下三种方式转换:

  • 手动声明 b’ ’
  • 字符编码 str.encoding()
  • 构造函数 bytes(’字符串‘,’编码方式‘),只能转换0-256范围内的数。

上述代码的转换中,因为ASCII的代码点与编码后的二进制数一致,因此显示时,是显示的一样,只是在最前面加一个b。

>>> s1 = 'abd'
>>> s2 = '优品课堂'
>>> ba = bytearray(s1,'utf-8')
>>> type(ba)
<class 'bytearray'>
>>> ba
bytearray(b'abd')
>>> ba[0]
97
>>> ba[0]=98
>>> ba
bytearray(b'bbd')
>>> ba.append(212)
>>> ba
bytearray(b'bbd\xd4')
>>> ba+b'c!'
bytearray(b'bbd\xd4c!')
>>> ba.decode('utf-8')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd4 in position 3: unexpected end of data
>>> 

bytearray的方法跟list的很多方法一致。
代码最后报错的原因是utf8对于大于127的数字是按照两位编码的,因此\xd4是大于127的数,但只有一个字节,因此报错。

BOM

f = open('date.txt', 'r', encoding='utf-8')
a = f.read()
print(a)
f.close()
f1 = open('date3.txt', 'w', encoding='utf-8-sig')
f1.write('优品课堂')
f1.close()
#只有在控制台才行
f2 = open('date3.txt', 'r', encoding='utf-8')
b = f2.read()
print(open('date3.txt','r',encoding='utf-8').read())
f2.close()
# 最后两行代码的输出
'\ufeff优品课堂'

当在编码的后面加上-gis,表示写入时,在字符串前加上字符顺序标记。当读取时,加上-gis,可以消除字符顺序标记。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值