首先了解python中bytes、str和unicode相关知识
bytes
和 str
怎么理解上面的内容呢?简单介绍一下编码
在计算机历史的早期,美国为代表的英语系国家主导了整个计算机行业,26个英文字母组成了多样的英语单词、语句、文章。因此,最早的字符编码规范是ASCII码,一种8位即1个字节的编码规范,它可以涵盖整个英语系的编码需要。8个比特位,可以没有重复的最多表示2的8次方(255)个字符。
随着计算机普及,各国语言都需要进行编码。ASCII的255位远远不够,于是标准组织制定出了叫做UNICODE的万国码,它规定任何一个字符(不管哪国的)至少以2个字节表示,可以更多。其中,英文字母就是用2个字节,而汉字是3个字节。这个编码虽然很好,满足了所有人的要求,但是它不兼容ASCII,同时还占用较多的空间和内存。因为,在计算机世界更多的字符是英文字母,明明可以1个字节就能够表示,非要用2个。于是UTF-8编码应运而生,它规定英文字母系列用1个字节表示,汉字用3个字节表示等等。因此,它兼容ASCII,可以解码早期的文档。UTF-8很快就得到了广泛的应用。
所以上述内容就很好理解了,bytes是原始的存储在磁盘上或网络流里面的二进制流,str是编码之后的文本字符。Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分,开发者不能以>
或+
等操作符号来混同bytes
和str
的实例。
>>> s = "中文"
>>> s
'中文'
>>> type(s)
<class 'str'>
>>> b = bytes(s, encoding='utf-8')
>>> b
b'\xe4\xb8\xad\xe6\x96\x87'
>>> type(b)
<class 'bytes'>
程序员经常需要用到str与bytes之间的转换,需要用到的是:
str.encode([encoding="utf-8"][,errors="strict"])
bytes.decode([encoding="utf-8"][,errors="strict"])
可以看到其默认使用utf-8编码。一般而言,在程序中我们会使用以下两个辅助函数实现字符转换
def to_str(bytes_or_str):
if isinstance(bytes_or_str, bytes):
value = bytes_or_str.decode('utf-8')
else:
value = bytes_or_str
return value
def to_bytes(bytes_or_str):
if isinstance(bytes_or_str, str):
value = bytes_or_str.encode('utf-8')
else:
value = bytes_or_str
return value
需要注意的是:
在读写文件中,Python3给open函数添加了命名为encoding=utf-8
的参数,所以只能传入unicode字符的str实例,如果要写入二进制需要指定’wb’。
def write_str(s):
with open('/tmp/random.bin','w') as f:
f.write(s)
def write_bytes(b):
with open('/tmp/random.bin','wb') as f:
f.write(b)