杰瑞科技汇

Python Unicode格式化如何正确处理?

Unicode vs. 字符串

要理解 Python 3 中一个非常重要的设计决策:

Python Unicode格式化如何正确处理?-图1
(图片来源网络,侵删)
  • 字符串:在 Python 3 中,str 类型是 Unicode 字符串,这意味着你写的任何字符串字面量,"你好""hello",其内部表示都是 Unicode,Python 3 默认会处理字符到 Unicode 码点的转换,你不需要像在 Python 2 中那样去关心“编码”问题,除非你需要将字符串转换成字节流(写入文件或网络传输)。

  • 字节串bytes 类型是字节序列,它只是原始的字节(0-255 的整数),没有字符编码的含义,当你需要与外部世界(文件系统、网络、其他程序)交互时,你需要将 str 编码成 bytes

Python 3 的 str 本身就是 Unicode 格式,所谓的 "Unicode 格式化",更准确地说是如何将变量(包括字符串、数字等)格式化到一个 Unicode 字符串中


Python 字符串格式化的演变

Python 提供了多种字符串格式化的方法,了解它们的演变有助于你写出更现代、更健壮的代码。

Python Unicode格式化如何正确处理?-图2
(图片来源网络,侵删)

操作符 (旧式字符串格式化)

这是从 C 语言继承来的方法,也是 Python 2 和早期 Python 3 中最常见的方式。

语法"格式化字符串" % (变量元组)

示例

name = "世界"
age = 18
# %s 会自动将任何变量转换为字符串
# %d 用于整数
# %.2f 用于浮点数,保留两位小数
info = "你好, %s! 你今年 %d 岁,体重 %.2f 公斤。" % (name, age, 65.5)
print(info)
# 输出: 你好, 世界! 你今年 18 岁,体重 65.50 公斤。

Unicode 处理: 在 Python 2 中, 操作符有时会遇到编码问题,需要小心处理,但在 Python 3 中,只要你的字符串是 str 类型(即 Unicode), 操作符就能很好地工作。

Python Unicode格式化如何正确处理?-图3
(图片来源网络,侵删)

缺点:当变量很多时,格式化字符串会变得难以阅读和维护,容易出错,比如顺序或类型不匹配。


str.format() 方法 (新式字符串格式化)

Python 2.6 和 Python 3 引入了 str.format() 方法,它比 操作符更灵活、更强大。

语法"格式化字符串 {}".format(变量)

示例

name = "Python"
version = 3.9
# 使用 {} 作为占位符
info = "语言: {}, 版本: {:.1f}".format(name, version)
print(info)
# 输出: 语言: Python, 版本: 3.9
# 可以通过索引指定位置
info2 = "{1} 的版本是 {0}".format(3.9, "Python")
print(info2)
# 输出: Python 的版本是 3.9
# 可以使用关键字参数
info3 = "{name} 的版本是 {version}".format(name="Python", version=3.9)
print(info3)
# 输出: Python 的版本是 3.9

Unicode 处理: 和 一样,在 Python 3 中,只要传入的变量是正确的类型,format() 方法会自动处理 Unicode,没有任何问题。

优点:可读性更好,功能更强大(如支持属性访问、数字格式化等)。


f-strings (格式化字符串字面量) (现代首选)

Python 3.6 引入了 f-strings,这是目前最推荐、最简洁、性能也最高的字符串格式化方法。

语法:在字符串前加上 fF,然后在字符串内部用 直接嵌入变量或表达式。

示例

name = "f-string"
version = 3.10
# 直接在字符串中嵌入变量
info = f"这是 {name},当前版本是 {version}"
print(info)
# 输出: 这是 f-string,当前版本是 3.10
# 可以直接嵌入表达式
a = 10
b = 20
print(f"a + b 的结果是 {a + b}")
# 输出: a + b 的结果是 30
# 可以调用函数
def get_greeting(name):
    return f"你好, {name}!"
print(get_greeting("Alice"))
# 输出: 你好, Alice!

Unicode 处理: f-strings 完美支持 Unicode,Python 3 会自动将花括号内的表达式结果转换为字符串并嵌入到最终的 Unicode 字符串中,这是最直观、最不易出错的方式。

优点

  • 简洁易读:语法最简单,代码意图最清晰。
  • 性能高:f-strings 在编译时被求值,比 format() 和 更快。
  • 功能强大:可以嵌入任意有效的 Python 表达式。

格式化 Unicode 字符串的最佳实践

现代代码:首选 f-strings

对于任何新的 Python 3.6+ 项目,都应该使用 f-strings。

# 好的实践
city = "北京"
population = 21540000
summary = f"{city} 是一个拥有 {population:,} 人口的大都市。" # , 是千位分隔符
print(summary)
# 输出: 北京 是一个拥有 21,540,000 人口的大都市。

处理非 Unicode 输入(如从文件或网络读取)

当你从外部来源(如读取一个以 gbk 编码保存的文本文件)获取数据时,你得到的是 bytes 对象,必须先解码成 str(Unicode)才能进行格式化。

# 假设我们从文件中读取了以下字节流,文件编码是 gbk
byte_data = b'\xB9\xE3\xD6\xDD\xCA\xA1\xCA\xA0'  # 这是 "你好世界" 的 gbk 编码
# 错误的做法:直接格式化 bytes
# 会报 TypeError: % format: a number is required, not bytes
# try:
#     info = "接收到的数据: %s" % byte_data
# except TypeError as e:
#     print(e)
# 正确的做法:先解码
# 使用 errors='ignore' 或 errors='replace' 来处理解码错误
unicode_str = byte_data.decode('gbk', errors='replace') # 'replace' 会将无法解码的字符替换为 �
print(f"解码后的字符串: {unicode_str}")
# 现在可以安全地格式化
final_info = f"处理后的信息: {unicode_str}"
print(final_info)
# 输出:
# 解码后的字符串: 你好世界
# 处理后的信息: 你好世界

控制输出格式(数字、日期等)

格式化不仅仅是插入变量,还包括控制变量的显示格式。

# 数字格式化
pi = 3.141592653589793
print(f"PI 精确到两位小数: {pi:.2f}")  # .2f 表示浮点数,保留两位小数
# 输出: PI 精确到两位小数: 3.14
# 百分比
percentage = 0.75
print(f"百分比表示: {percentage:.0%}")  # .0% 表示百分比,不保留小数
# 输出: 百分比表示: 75%
# 千位分隔符
large_num = 1000000
print(f"带千位分隔符的数字: {large_num:,}")
# 输出: 带千位分隔符的数字: 1,000,000
# 日期时间格式化 (需要 datetime 模块)
from datetime import datetime
now = datetime.now()
print(f"当前日期和时间 (标准格式): {now}")
print(f"自定义格式: {now.strftime('%Y-%m-%d %H:%M:%S')}")
# 输出 (示例):
# 当前日期和时间 (标准格式): 2025-10-27 10:30:00.123456
# 自定义格式: 2025-10-27 10:30:00
方法 Python 版本 优点 缺点 推荐度
操作符 All 简单,兼容性好 功能有限,可读性差,易出错 仅用于维护旧代码
str.format() 6+ 功能强大,可读性好 比 f-strings 稍长,性能稍低 良好,但非首选
f-strings 6+ 最简洁、最易读、性能最高 需要 Python 3.6+ 强烈推荐 (现代标准)

核心要点

  1. Python 3 的 str Unicode,你无需担心内部表示。
  2. 专注于如何将数据优雅地组合成 str
  3. 编写新代码时,请毫不犹豫地使用 f-strings,它们是 Python 字符串格式化的未来,也是最方便、最强大的工具。
  4. 当处理来自外部(文件、网络)的 bytes 数据时,第一步永远是 decode(),将其转换为 str,然后再进行格式化。
分享:
扫描分享到社交APP
上一篇
下一篇