Python中的bytes和str类型,二进制与字符串


Python中的bytes和str类型,解决ValueError: binary mode doesn't take an encoding argument问题。

TL;DR

关于文件的保存和读取:

  • 保存和读取非二进制文件:使用w和r模式
  • 保存和读取二进制文件:使用wb和rb模式

Python中用bytes类型(具体地说8位值)表示二进制字节序列,用str类型(具体地说是unicode)表示字符串序列

  • bytes的实例有8位值
  • str的实例有Unicode

str和bytes

str 是字符串,通过unicode字符来表示。

bytes 只负责以字节序列的形式(二进制形式)来存储数据,至于这些数据到底表示什么内容(字符串、数字、图片、音频等),完全由程序的解析方式决定。如果采用合适的字符编码方式(字符集),字节串可以恢复成字符串;反之亦然,字符串也可以转换成字节串。

bytes 类型的数据非常适合在互联网上传输,可以用于网络通信编程;bytes 也可以用来存储图片、音频、视频等二进制格式的文件。

把Unicode表示为二进制数据,最常见的就是UTF-8编码。

需要注意,要把encode和decode放在程序的最外围,程序的核心部分应该使用Unicode字符类型。

关于Unicode

  • 在Python 3版本中,把’xxx’和u’xxx’统一成Unicode编码,即写不写前缀u都是一样的。
  • 在Python 3版本中,所有的字符串都是使用Unicode编码的字符串序列。
  • Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是 Unicode,由 str 类型表示,二进制数据则由 bytes 类型表示。Python 3 不会以任意隐式的方式混用 str 和 bytes ,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然)。

一些相关的命令

查看默认的编码方式:

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

通过不同方式创建bytes对象:

#通过构造函数创建空 bytes
b1 = bytes()

#通过空字符串创建空 bytes
b2 = b''

#通过b前缀将字符串转换成 bytes
b3 = b'hellow'
print("b3: ", b3)
print(b3[3])
print(b3[3:])

# b3:  b'hellow'
# 108
# b'low'

#为 bytes() 方法指定字符集
b4 = bytes('测试一下', encoding='UTF-8')
print("b4: ", b4)
# b4:  b'\xe6\xb5\x8b\xe8\xaf\x95\xe4\xb8\x80\xe4\xb8\x8b'
print(b4.decode('utf-8'))
# '测试一下'

#通过 encode() 方法将字符串转换成 bytes
b5 = '测试一下'.encode('UTF-8')
print("b5: ", b5)
# b5:  b'\xe6\xb5\x8b\xe8\xaf\x95\xe4\xb8\x80\xe4\xb8\x8b'

遇到的问题

ValueError: binary mode doesn’t take an encoding argument

因为下面这个dic是直接存储到硬盘上的bytes类型,读取的时候,不能使用encoding system。所以下面在with的语句里,删除了encoding=’utf-8’。另外使用’rb’, 必须有b才行。另外此时f是bytes类型,必须使用read变成str才行。


path = '/Users/smap10/Project/company-name/data/dictionaries/sudachi-dictionary-20191224/system_full.dic'
with open(path, 'rb') as f:
    lines = []
    content = f.read() # 如果文件不太大的话,可以直接读到内存里
    for line in content:
        lines.append(line)

参考资料


文章作者: BrambleXu
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 BrambleXu !
评论
  目录