首页 > 应用开发 > Python > Python 2 到 3 字符串编码兼容性问题
1. Python 2 和 Python 3 的字符串类型差异
特性 Python 2 Python 3
默认字符串类型 str(字节串 bytes) str(Unicode 字符串)
Unicode 字符串 unicode str
字节串 str bytes
字符串前缀 u"..." 表示 Unicode b"..." 表示 bytes, u"..." 可兼容
len("中文") 6(因为每个字占两个字节) 2(每个字符一个 Unicode code point)
所以在 Python 2 中:
# Python 2
s1 = "abc" # 字节串
s2 = u"abc" # Unicode
type(s1) # <type 'str'>
type(s2) # <type 'unicode'>
Python 3 中:
# Python 3
s1 = "abc" # Unicode 字符串
s2 = b"abc" # 字节串
type(s1) # <class 'str'>
type(s2) # <class 'bytes'>
2. 常见问题
2.1 字符串与字节串混用
Python 3 中,str 和 bytes 不可混合运算,否则报 TypeError:
b = b"bytes"
s = "str"
b + s # TypeError: can't concat bytes to str
Python 2 中这通常不会报错(但可能乱码),所以代码迁移时容易出问题。
2.2 文件读写默认编码
Python 2:
f = open("test.txt", "r")
data = f.read() # 返回字节串
Python 3:
f = open("test.txt", "r", encoding="utf-8")
data = f.read() # 返回 Unicode 字符串
坑点:在 Python 3 不指定 encoding,会用系统默认编码,可能导致读取中文报错。
2.3 print 与编码
Python 2:
# -*- coding: utf-8 -*-
print u"中文"
Python 3:
print("中文") # 已经是 Unicode
在 Python 2 如果用 print "中文" 而不是 u"中文",可能输出乱码。
2.4 字符串函数和方法差异
功能 Python 2 Python 3
encode() Unicode → bytes str → bytes
decode() bytes → Unicode bytes → str
.format() 支持 Unicode 同样支持 Unicode
basestring 有(str + unicode) 无
迁移时需要注意:
# Python 2
u = u"中文"
s = u.encode("utf-8") # bytes
# Python 3
s = "中文".encode("utf-8") # bytes
3. 兼容 Python 2/3 的做法
3.1 使用 six 库
import six
if six.PY2:
text_type = unicode
else:
text_type = str
def to_unicode(s):
if isinstance(s, text_type):
return s
return s.decode("utf-8")
six 提供了 b()、u() 等工具,方便同时写 Python 2/3 的代码。
3.2 文件操作统一编码
import io
# Python 2/3 统一方式
with io.open("file.txt", "r", encoding="utf-8") as f:
content = f.read()
io.open 在 Python 2 中也是可用的,返回 Unicode 字符串。
3.3 __future__ 的 Unicode 支持
在 Python 2 里,推荐加上:
from __future__ import unicode_literals
这样默认字符串就是 Unicode,减少编码转换问题。
3.4 避免隐式 byte/str 转换
Python 2 写 str 操作字节,Python 3 写 bytes。
永远明确 encode/decode,不要隐式转换。
对外接口尽量统一为 Unicode。
4. 总结
核心区别:Python 2 默认 str = bytes,Python 3 默认 str = Unicode。
常见坑:字节串 vs Unicode 混用、文件读写、print 输出、字符串函数行为。
迁移策略:
明确使用 encode/decode
文件读写指定 encoding="utf-8"
使用 six 或 future 做兼容
尽量统一接口为 Unicode
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70050070/viewspace-3171527/ ,如需转载,请注明出处,否则将追究法律责任。