← [ BACK_TO_NOTES ]

Python 字符串与字节

str 是不可变 Unicode 文本,bytes 是不可变字节序列;在文件/网络边界显式编码解码。

#concept #growing #dev #python #python

[!info] related notes

Python 字符串与字节

这个概念为什么出现

用户看见的是文本,磁盘和网卡上是字节。Python 3 强制分开:

  • str:Unicode 文本
  • bytes/bytearray:字节

混用会在读写文件、HTTP、加密时出现 TypeError 或乱码。

[!abstract] 一句话理解 str 不可变文本;bytes 不可变字节串;越过 I/O 边界时用明确编码 encode/decode(常见 UTF-8)。

最小可运行示例

先把示例放进业务场景,再看代码:

场景:客服备注写入 UTF-8 文件并回读

工单备注含中文。写入磁盘必须是字节;读回要按同一编码解码。

# ticket_note_codec.py
# 业务意图:把中文备注安全写入字节并解码回来。
# 教学点:
# - str.encode / bytes.decode;
# - len(str) 计 Unicode 码点,len(bytes) 计字节;
# - 错误处理 errors= 可选。

from pathlib import Path
from tempfile import TemporaryDirectory


def save_note(path: Path, note: str) -> None:
    data = note.encode("utf-8")  # 文本 -> 字节
    path.write_bytes(data)


def load_note(path: Path) -> str:
    return path.read_bytes().decode("utf-8")


def main() -> None:
    text = "用户说:无法登录"
    with TemporaryDirectory(prefix="ticket-note-") as temp_dir:
        p = Path(temp_dir) / "note.txt"
        save_note(p, text)
        back = load_note(p)
    print("roundtrip:", back)
    print("codepoints:", len(text), "utf8 bytes:", len(text.encode("utf-8")))


if __name__ == "__main__":
    main()

建议运行:

python ticket_note_codec.py

期望输出:

roundtrip: 用户说:无法登录
codepoints: 8 utf8 bytes: 24

结合场景再看三个关注点

  1. len(str) 是码点数,不一定是用户感知字符数;组合字符和 emoji 序列可能含多个码点。此例每个码点编码为 3 个 UTF-8 字节。
  2. 编解码编码必须一致,否则乱码或异常。
  3. 文本模式 open(..., encoding="utf-8") 可自动编解码。

核心概念与准确模型

类型含义可变
strUnicode 码点序列否
bytes0–255 字节否
bytearray可变字节是
  • f-string、format、拼接 +/join
  • 常用方法:split/strip/replace/startswith
  • 原始字符串 r"..." 减少反斜杠转义

边界情况与反直觉行为

  1. str 与 bytes 不能隐式拼接。
  2. str.encode()/bytes.decode() 默认 UTF-8,但文本文件 open() 的默认编码受解释器模式/环境影响;按文件协议显式指定,不能混同两个默认值。
  3. 相同视觉文本可能有不同码点序列,默认 == 不做 NFC/NFD 规范化;需按业务协议决定是否规范化。

常见误区

[!warning] 常见误区:把 Python 2 的“str 即字节”直觉搬到 3 错误理解:字符串就是字节数组。
正确模型:文本与字节分离;边界显式转换。

工程实践

  • UTF-8 是常见约定,但仍须遵守外部文件/协议指定编码;errors=“ignore” 会丢失数据,不能当作通用乱码修复。
  • 日志与 API JSON 用文本;签名/哈希用字节。
  • 大文本拼接用 join 或 IO 缓冲;流式读取字节时,块边界可能截断多字节字符,应使用文本流或增量解码器。

本节总结

先分清文本层与字节层,再处理切片、长度与 I/O。乱码问题几乎总是边界编码问题。

自测题

  1. 为什么示例里 chars 与 utf8 bytes 不同?
  2. b"hi" + "hi" 会怎样?
参考答案
  1. 中文在 UTF-8 中多字节编码。
  2. TypeError,bytes 与 str 不能直接加。

延伸阅读与资料来源

资料类型支撑内容
Text Sequence Type文档str
Binary Sequence Types文档bytes
Unicode HOWTOHOWTO编码实践
创建于 2026/7/15 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本