Effective Python 读书笔记——第 3 条

344 阅读3分钟

Effective Python 读书笔记——第 3 条


第 3 条:了解 bytes、str 与 unicode 的区别

Python 3 中有两种字符串:

  • str 类型:它的实例包含 Unicode 字符
  • bytes 类型:它的实例包含原始的字节

Python 2 中也有两种字符串:

  • unicode 类型:它的实例包含 Unicode 字符
  • str 类型:它的实例包含原始的字节

二进制数据 --> Unicode 字符:encode 方法编码 Unicode 字符 --> 二进制数据:decode 解码

编码和解码的工作要放在界面最外围,核心部分用 Unicode 字符串。 并且让程序可以接受多种文本编码,而保证输出一种编码形式(最好是 UTF-8)。

要针对 Python 3Python 2 编写两个辅助 helper 函数 Python 3

  • 总是返回 str
  • 总是返回 bytes
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  # Instance of str


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  # Instance of bytes

Python 2

  • 总是返回 unicode
  • 总是返回 str
def to_unicode(unicode_or_str):
    if isinstance(unicode_or_str, str):
        value = unicode_or_str.decode('utf-8')
    else:
        value = unicode_or_str
    return value  # Instance of unicode


def to_str(unicode_or_str):
    if isinstance(unicode_or_str, unicode):
        value = unicode_or_str.encode('utf-8')
    else:
        value = unicode_or_str
    return value  # Instance of str

ASCII 码相关知识补充

ASCII第一次以规范标准的型态发表是在1967年,最后一次更新则是在1986年,至今为止共定义了128个字符,其中33个字符无法显示(这是以现今操作系统为依归,但在DOS模式下可显示出一些诸如笑脸、扑克牌花式等8-bit符号),且这33个字符多数都已是陈废的控制字符,控制字符的用途主要是用来操控已经处理过的文字,在33个字符之外的是95个可显示的字符,包含用键盘敲下空白键所产生的空白字符也算1个可显示字符(显示为空白)。

注意点:

  • Python 2 中,如果 str 只包含 7ASCII 字符,那么 unicodestr 就成了同一种类型。但是在 Python 3 中这两者绝对不等价,空字符串也不行。

    • 可以用 + 连接 strunicode
    • 可用等价于不等价操作符进行比较
    • 格式字符串中可以用 '%s' 等形式代表 unicode 实例
    • 可以用 strunicode 给函数传参
  • Python 3open 函数默认使用 UTF-8 编码格式 系统本地的编码格式来操作文件,不能直接往里面写二进制数据 f.write(os.urandom(10)),会报错。在 Python 2 中文件操作的默认编码格式是二进制形式。同时适配 Python 2Python 3 的写法是:

with open('/tmp/random.bin', 'wb') as f:
    f.write(os.urandom(10))

读二进制文件也是一样,要用 rb,可以适配 Python 3Python 2

【注】 原书这句话有误,在 Python 3 中,open 函数以文本模式操作文件时,如果不指定编码,该编码是依赖于平台的。 以下内容来自官网:docs.python.org/3/library/f… encoding is the name of the encoding used to decode or encode the file. This should only be used in text mode. The default encoding is platform dependent (whatever locale.getpreferredencoding() returns), but any text encoding supported by Python can be used. See the codecs module for the list of supported encodings.

os.urandom(size) 随机生成 size 个字节的二进制数据。

文件句柄 file handle 其实是一种标识符或指针。