Python3中decode、encode、bytes与str详解

首先了解python中bytes、str和unicode相关知识

  • python3中有力阆中表示字符串的类型:bytesstr
    • bytes:包含原始的字节,每个字节有8个二进制位。
    • str:包含实例的Unicode字符。

怎么理解上面的内容呢?简单介绍一下编码

在计算机历史的早期,美国为代表的英语系国家主导了整个计算机行业,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最重要的新特性之一是对字符串和二进制数据流做了明确的区分,开发者不能以>+等操作符号来混同bytesstr的实例。

>>> 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之间的转换,需要用到的是:

  • encode():将str转为bytes,str.encode([encoding="utf-8"][,errors="strict"])
  • decode():将bytes转为str,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

需要注意的是:

  • 在将字符串存入磁盘和从磁盘读取字符串的过程中,Python自动地帮你完成了编码和解码的工作(默认采用utf-8),你不需要关心它的过程。
  • 使用bytes类型,实质上是告诉Python,不需要它帮你自动地完成编码和解码的工作,而是用户自己手动进行,并指定编码格式。
  • Python已经严格区分了bytes和str两种数据类型,你不能在需要bytes类型参数的时候使用str参数,反之亦然。这点在读写磁盘文件时容易碰到。

在读写文件中,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)

你可能感兴趣的:(python开发,python,开发语言,编码)