这篇教程Effective Python bytes 与 str 的区别写得很实用,希望能帮到您。
1、Python 有两种类型可以表示字符序列 bytes :实例包含的是 原始数据 ,即 8 位的无符号值(通常按照 ASCII 编码 标准来显示) str :实例包含的是 Unicode 码点(code point,也叫作代码点),这些码点与人类语言之中的文本字符相对应 a = b'h/x6511o'print(list(a))print(a)a = 'a//u300 propos'print(list(a))print(a)# 输出结果[104, 101, 49, 49, 111]b'he11o'['a', '//', 'u', '3', '0', '0', ' ', 'p', 'r', 'o', 'p', 'o', 's']a/u300 propos
2、Unicode 数据和二进制数据转换 - 把
Unicode 数据转换成二进制数据,必须调用 str 的 encode 方法(编码) - 把二进制数据转换成
Unicode 数据,必须调用 bytes 的 decode 方法(解码) - 调用这些方法时,可以明确指出字符集编码,也可以采用系统默认的方案,通常是 UTF-8
3、使用原始的 8 位值与 Unicode 字符串使用原始的 8 位值与 Unicode 字符串时需要注意的两个问题: - 该问题等价于:使用
bytes 和 str 时需要注意的两个问题
3.1 问题一:bytes 和 str 的实例互不兼容使用 + 操作符:
# bytes+bytesprint(b'a' + b'1')# str+strprint('b' + '2')# 输出结果b'a1'b2 bytes + bytes ,str + str 都是允许的 - 但
bytes + str 会报错 # bytes+strprint('c' + b'2')# 输出结果print('c' + b'2')TypeError: can only concatenate str (not "bytes") to str 同类型之间也可以用二元操作符来比较大小 assert b'c' > b'a'assert 'c' > 'a' 但 bytes 和 str 之间用二元操作符也会报错 assert b'c' > 'a'# 输出结果 assert b'c' > 'a'TypeError: '>' not supported between instances of 'bytes' and 'str' 判断 bytes 与 str 实例是否相等 两个类型的实例相比较总会为 False ,即使字符完全相同 # 判断 str、bytesprint('a' == b'a')# 输出结果False 格式化字符串中的 %s
两种类型的实例都可以出现在 % 操作符的右侧,用来替换左侧那个格式字符串(format string )里面的 %s 但是!如果格式字符串是 bytes 类型,那么 不能 用 str 实例来替换其中的 %s ,因为 Python 不知道这个 str 应该按照什么字符集来编码 # %print(b'red %s' % 'blue')# 输出结果 print(b'red %s' % 'blue')TypeError: %b requires a bytes-like object, or an object that implements __bytes__, not 'str' 但是!反过来却可以,如果格式字符串是 str 类型,则 可以 用bytes 实例来替换其中的 %s ,但结果可能不是预期结果 # % print('red %s' % b'blue')# 输出结果red b'blue' 这样会让系统在 bytes 实例上面调用 __repr__ 方法 调用结果替换格式字符串里的 %s,因此程序会直接输出 b'blue' ,而不是输出 blue
3.2问题二:操作文件句柄时需要使用 Unicode 字符串操作不能使用原始的 bytes 向文件写入二进制数据会报错:
# 写入二进制数据with open('test.txt', "w+") as f: f.write(b"/xf1/xf2")# 输出结果 f.write(b"/xf1/xf2")TypeError: write() argument must be str, not bytes - 报错是因为
w 模式必须以 文本 模式写入 - 将模式改成
wb 即可正常写入二进制数据 with open('test.txt', "wb") as f: f.write(b"/xf1/xf2")读取文件中二进制数据with open('test.txt', "r+") as f: f.read()# 输出结果 (result, consumed) = self._buffer_decode(data, self.errors, final)UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 0: invalid continuation byte - 报错是因为 r 模式必须以 文本 模式读取
- 以文本模式操纵文件句柄时,系统会采用 默认的文本编码 方案处理二进制数据
- 所以,上面那种写法会让系统通过
bytes.decode 把这份数据解码成 str 字符串,再用 str.encode 把字符串编码成二进制值 - 然而对于大多数系统来说,默认的文本编码方案是
UTF-8 ,所以系统很可能会把 b'/xf1/xf2/xf3/xf4/xf5' 当成 UTF-8 格式的字符串去解码,于是就会出现上面那样的错误 将模式改成 rb 即可正常读取二进制数据:
with open('test.txt', "rb") as f: print(b"/xf1/xf2" == f.read())# 输出结果True 另一种改法,设置 encoding 参数指定字符串编码: with open('test.txt', "r", encoding="cp1252") as f: print(f.read())# 输出结果ñò 这样也不会有异常了 需要注意:当前操作系统默认的字符集编码,Python 一行代码查看当前操作系统默认的编码标准 在 cmd 中执行: > python3 -c 'import locale; print(locale.getpreferredencoding())'UTF-8
到此这篇关于Effective Python bytes 与 str 的区别的文章就介绍到这了,更多相关Python bytes 与 str 的区别内容请搜索51zixue.net以前的文章或继续浏览下面的相关文章希望大家以后多多支持51zixue.net! python中字典和列表的相互嵌套问题详解 Python 中使用 argparse 解析命令行参数 |