如何用同一代码在Python 2与Python 3中写入Unicode文本到文件?
解决Python 2/3兼容的Unicode文件写入问题
嗨,这个编码坑我可太熟悉了!咱们一步步把它搞定:
问题根源
你导入了__future__的unicode_literals,所以txt = u'his$…\n'在Python 2里是Unicode字符串,但用内置open()打开文件时,Python 2默认用ASCII编码处理写入的Unicode内容——那个省略号\u2026是ASCII范围外的字符,自然就触发UnicodeEncodeError了。Python 3默认编码是系统默认(一般是UTF-8),所以没这个问题,但咱们得兼顾两个版本。
最优解决方案:用io.open()替代内置open()
io模块在Python 2.6+和Python 3全版本都支持,统一了文件操作的编码逻辑,是跨版本兼容的最佳选择。直接看代码:
from __future__ import unicode_literals import io # 用UTF-8编码打开文件,with语句自动管理文件关闭 with io.open("/tmp/test", "w", encoding="utf-8") as fp: txt = u'his$…\n' fp.write(txt)
这段代码在两个版本里都能正常工作:
- Python 2中,
io.open()会创建Unicode文件对象,写入Unicode字符串时自动按指定的utf-8编码转成字节写入; - Python 3中,
io.open()和内置open()行为完全一致,直接写字符串就行。
备选方案:手动编码+版本判断(不推荐)
如果非要用内置open(),可以通过版本判断分别处理,但这种方式代码冗余,不如上面的方法优雅:
from __future__ import unicode_literals import sys txt = u'his$…\n' if sys.version_info[0] == 2: # Python 2里手动把Unicode字符串编码成字节串 with open("/tmp/test", "w") as fp: fp.write(txt.encode("utf-8")) else: # Python 3里直接写字符串,指定编码 with open("/tmp/test", "w", encoding="utf-8") as fp: fp.write(txt)
额外提醒
导入unicode_literals只是让字符串字面量默认变成Unicode,但Python 2的内置文件操作还是严格区分字节串和Unicode的,这是很多人踩坑的点。用io模块的文件操作能彻底避开这种版本差异带来的编码问题。
内容的提问来源于stack exchange,提问作者James T
相关产品推荐
相关产品推荐

