Python 2 中文编码处理与文件读写详解

顾言
顾言
发布时间:2026-10-16 | 5人浏览过
原创

本文详细解析 Python 2 中处理中文编码的常见陷阱与解决方案。涵盖如何正确设置文件编码声明、理解 str 与 unicode 的区别,以及在 Windows 环境下处理 ANSI 和 UTF-8 文件时的编码转换技巧。重点讲解了 BOM 头处理、print 输出机制及跨平台编码兼容性问题,帮助开发者避免中文乱码错误。

Python 版本检查与编码声明基础

首先确认当前 Python 环境的版本信息。


>>> import sys


>>> sys.version


'2.5.1 (r251:54863, Apr 18 2007, 08:51:08) [MSC v.1310 32 bit (Intel)]'



(一)

使用记事本新建一个名为 ChineseTest.py 的脚本文件,默认保存格式为 ANSI 编码。


s = "中文"


print s



尝试运行该脚本进行测试。


E:\Project\Python\Test>python ChineseTest.py


File "ChineseTest.py", line 1


SyntaxError: Non-ASCII character '\xd6' in file ChineseTest.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details



尝试将文件编码修改为 UTF-8 格式,再次运行。


E:\Project\Python\Test>python ChineseTest.py


File "ChineseTest.py", line 1


SyntaxError: Non-ASCII character '\xe4' in file ChineseTest.py on line 1, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details



上述修改并未解决问题。


既然错误提示提供了相关文档链接,查阅 PEP-0263 可知,若源代码中包含非 ASCII 字符,必须在文件的第一行或第二行显式声明编码格式。因此,将 ChineseTest.py 的编码改回 ANSI,并在文件首行添加编码声明。


# coding=gbk


s = "中文"


print s



再次执行脚本。


E:\Project\Python\Test>python ChineseTest.py


中文



此时程序运行正常。


(二)

str 与 unicode 长度及转换差异

接下来检查字符串的长度属性。


# coding=gbk


s = "中文"


print len(s)


结果:4。


变量 s 的类型为 str,在 GBK 编码下,每个中文字符占用两个字节,因此长度为 4。


尝试使用 unicode 类型进行对比处理。


# coding=gbk


s = "中文"


s1 = u"中文"


s2 = unicode(s, "gbk") # 若省略编码参数,Python 默认使用 ASCII 解码


s3 = s.decode("gbk") # 将 str 转换为 unicode 需使用 decode 方法,unicode() 函数功能与此相同


print len(s1)


print len(s2)


print len(s3)


输出结果如下。


2


2


2


(三)

文件读写中的编码处理与 BOM 问题

进一步探讨文件读取时的编码处理。


创建一个名为 test.txt 的文件,保存格式为 ANSI,内容包含英文和中文。


abc中文


使用 Python 直接读取该文件。


# coding=gbk


print open("Test.txt").read()


结果:abc中文


将 test.txt 的编码格式更改为 UTF-8 后再次读取。


结果:abc涓枃


显然,直接读取 UTF-8 编码的文件会导致乱码,需要进行解码操作。


# coding=gbk


import codecs


print open("Test.txt").read().decode("utf-8")


结果:abc中文


上述 test.txt 文件由 Editplus 编辑保存。然而,若使用 Windows 自带的记事本编辑并保存为 UTF-8 格式,运行时会遇到错误。


运行时抛出异常。


Traceback (most recent call last):


File "ChineseTest.py", line 3, in <module>


print open("Test.txt").read().decode("utf-8")


UnicodeEncodeError: 'gbk' codec can't encode character u'\ufeff' in position 0: illegal multibyte sequence



原因在于,部分编辑器(如 Notepad)在保存 UTF-8 文件时,会在文件头部插入三个不可见的字节(0xEF 0xBB 0xBF),即 BOM(Byte Order Mark)。


因此,在读取此类文件时需手动去除 BOM 头。Python 的 codecs 模块中定义了该常量。


# coding=gbk


import codecs


data = open("Test.txt").read()


if data[:3] == codecs.BOM_UTF8:


data = data[3:]


print data.decode("utf-8")


结果:abc中文



(四)一点遗留问题

print 输出机制与编码选择原理

在前文示例中,我们使用 unicode() 函数和 decode() 方法将 str 转换为 unicode,并指定了 "gbk" 编码。这是否仅仅因为编码声明中使用了 gbk?


初步推测与编码声明 # coding=gbk 有关,但实际情况并非如此简单。


修改源文件的编码声明为 utf-8 进行测试。


# coding=utf-8


s = "中文"


print unicode(s, "utf-8")


运行脚本,出现报错。


Traceback (most recent call last):


File "ChineseTest.py", line 3, in <module>


s = unicode(s, "utf-8")


UnicodeDecodeError: 'utf8' codec can't decode bytes in position 0-1: invalid data


此前正常是因为源文件编码与解码编码均为 gbk。此处即使统一使用 utf-8,依然报错,说明问题不在于编码声明的一致性。


进一步测试,若保持源文件编码为 utf-8,但转换时仍使用 gbk 解码。


# coding=utf-8


s = "中文"


print unicode(s, "gbk")


结果:中文


查阅英文资料,其解释了 Python 中 print 语句的工作原理。


When Python executes a print statement, it simply passes the output to the operating system (using fwrite() or something like it), and some other program is responsible for actually displaying that output on the screen. For example, on Windows, it might be the Windows console subsystem that displays the result. Or if you're using Windows and running Python on a Unix box somewhere else, your Windows SSH client is actually responsible for displaying the data. If you are running Python in an xterm on Unix, then xterm and your X server handle the display. <>



To print data reliably, you must know the encoding that this display program expects.



简而言之,Python 的 print 函数直接将字符串传递给操作系统,因此必须将 str 解码为与操作系统终端期望的编码格式一致。在 Windows 系统中,默认编码为 CP936(与 GBK 基本相同),因此使用 gbk 解码可以正常显示。


最后进行验证测试。


# coding=utf-8


s = "中文"


print unicode(s, "cp936")


结果:中文

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表