Python 字符串和编码
本章节主要讲解 什么是编码?,编码的基础概念,制与字符集,编码与解码过程,Python 中的字符串与编码,Python 字符串简介,编码与解码操作,字符串与字节类型,注意事项,字符串格式化,旧式格式化:%,format() 方法,f-string(Python )。
1. 什么是编码?
1.1 编码的基础概念
计算机只理解二进制(0和1),但我们日常使用的文字(如字母、汉字)需要通过编码转换为二进制,存储或传输后再解码还原。编码就像一座桥梁,将人类语言与计算机的二进制世界连接起来。
- 字符:人类可读的符号,如
A
、你
。 - 编码:将字符映射为二进制的规则。
- 解码:将二进制转换回字符。
1.2 二进制与字符集
计算机用字节(8位二进制,范围0-255)存储数据。早期计算机需要将字符映射到这些字节,这就是字符集的起源。
- ASCII:美国信息交换标准代码,用7位二进制(0-127)表示英文字母、数字和符号(如
A
是 65,a
是 97)。简单但不支持中文等复杂字符。 - Unicode:统一字符集,为全球所有字符分配唯一编号(码点),如
A
是 U+0041,你
是 U+4F60。Unicode 只定义编号,不定义存储方式。 - UTF-8:Unicode 的变长编码方案,常用格式。用1-4字节存储字符:
- ASCII 字符(如
A
)用1字节,与 ASCII 兼容。 - 汉字等用3字节,特殊字符可能用4字节。
- 优点:节省空间,广泛用于网络和文件。
- ASCII 字符(如
其他编码如 GBK(中文)、UTF-16、UTF-32 也有使用,但 UTF-8 是现代标准。
1.3 编码与解码过程
- 编码:字符 → 二进制(如
你
→ UTF-8 的E4 BD A0
)。 - 解码:二进制 → 字符(反向过程)。
错误编码或解码会导致乱码。例如,用 GBK 解码 UTF-8 数据会出错。
2. Python 中的字符串与编码
2.1 Python 字符串简介
Python3 中,字符串是 Unicode 字符序列,用单引号 '
、双引号 "
或三引号 '''
定义:
my_str = "Hello, 你好"
print(my_str) # 输出: Hello, 你好
- Python3 默认使用 Unicode 存储字符串,开发者无需担心底层存储。
- 字符串是不可变的,修改会创建新字符串。
2.2 编码与解码操作
Python 提供 encode()
和 decode()
方法处理字符串与字节之间的转换:
encode(encoding='utf-8')
:将字符串编码为字节(bytes
类型)。decode(encoding='utf-8')
:将字节解码为字符串。
text = "你好"
# 编码为 UTF-8 字节
encoded = text.encode('utf-8')
print(encoded) # 输出: b'\xe4\xbd\xa0\xe5\xa5\xbd'
# 解码回字符串
decoded = encoded.decode('utf-8')
print(decoded) # 输出: 你好
注意:
- 常用编码:
utf-8
(默认)、ascii
、gbk
。 - 错误编码/解码抛出
UnicodeEncodeError
或UnicodeDecodeError
。
# 错误示例
text = "你好"
encoded = text.encode('ascii') # 抛出 UnicodeEncodeError,ASCII 不支持中文
2.3 字符串与字节类型
- 字符串(str):Unicode 字符序列,人类可读。
- 字节(bytes):二进制数据,前缀
b
,如b'hello'
。 - 两者通过
encode()
和decode()
互转。
# 字节类型
byte_data = b'hello'
print(byte_data) # 输出: b'hello'
print(byte_data[0]) # 输出: 104('h' 的 ASCII 值)
print(byte_data[0:2]) # 切片,输出: b'he'
print(len(byte_data)) # 字节长度,输出: 5
# 字节转字符串
text = byte_data.decode('utf-8')
print(text) # 输出: hello
字符串与字节的区别
特性 | 字符串 (str) | 字节 (bytes) |
---|---|---|
数据类型 | Unicode 字符 | 二进制数据 |
可读性 | 人类可读 | 通常不可读 |
用途 | 文本处理 | 文件、网络传输 |
可变性 | 不可变 | 不可变 |
前缀 | 无 | b |
2.4 注意事项
- 默认编码:
- Python3 源码文件默认 UTF-8,若文件包含非 ASCII 字符,需在
文件头部声明编码。
- 终端、数据库等可能使用其他编码,需统一或转换。
- Python3 源码文件默认 UTF-8,若文件包含非 ASCII 字符,需在
- 文件读写:
- 打开文件时指定编码,如
open('file.txt', encoding='utf-8')
。 - 避免使用
open('file.txt', 'rb')
直接读字节,易出错。
- 打开文件时指定编码,如
- 网络传输:
- 数据传输前编码为字节,接收后解码。
- 确保发送方和接收方编码一致。
- 乱码处理:
- 为了避免乱码问题,应当始终坚持使用UTF-8编码对
str
和bytes
进行转换。 - 乱码常因编码不匹配,尝试用正确编码解码,可用
chardet
库检测编码。
- 为了避免乱码问题,应当始终坚持使用UTF-8编码对
import chardet
data = b'\xe4\xbd\xa0\xe5\xa5\xbd'
print(chardet.detect(data)) # 输出: {'encoding': 'utf-8', ...}
文件头部声明源文件编码格式,表明解释器在读取此文件时要用解码格式。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
3. 字符串格式化
Python 提供多种格式化字符串的方法,推荐使用 format()
和 f-string
。
3.1 旧式格式化:%
- 使用
%
占位符,类似 C 语言。 - 不推荐,易出错且可读性差。
name = "Alice"
age = 25
print("Name: %s, Age: %d" % (name, age)) # 输出: Name: Alice, Age: 25
3.2 format() 方法
- 使用
{}
占位符,支持位置和关键字参数。 - 灵活且可读性好。
# 位置参数
print("Name: {}, Age: {}".format("Alice", 25)) # 输出: Name: Alice, Age: 25
# 关键字参数
print("Name: {name}, Age: {age}".format(name="Alice", age=25)) # 输出: Name: Alice, Age: 25
# 格式控制
print("Pi: {:.2f}".format(3.14159)) # 输出: Pi: 3.14
3.3 f-string(Python 3.6+)
- 前缀
f
的字符串,内嵌变量和表达式。 - 简洁高效,推荐使用。
name = "Alice"
age = 25
print(f"Name: {name}, Age: {age}") # 输出: Name: Alice, Age: 25
# 表达式
print(f"Next year: {age + 1}") # 输出: Next year: 26
# 格式控制
pi = 3.14159
print(f"Pi: {pi:.2f}") # 输出: Pi: 3.14
注意:
f-string
不可在 Python 3.6 以下版本使用。- 格式化时,注意数据类型和格式代码(如
f
浮点,d
整数)。
常见的占位符有
占位符 | 替换内容 |
---|---|
%d | 整数 |
%f | 浮点数 |
%s | 字符串 |
%x | 十六进制整数 |
4. 总结
- 编码:将字符转换为二进制,Python3 字符串默认 Unicode。
- 编码操作:
encode()
和decode()
处理字符串与字节转换。 - 注意事项:文件、终端、网络传输需统一编码,避免乱码。
- 格式化:推荐
format()
和f-string
,简洁高效。
通过本教程,你应能理解编码基础、Python 字符串的编码处理及格式化方法,具备处理实际问题的能力。