转自:http://hi.baidu.com/daping_zhang/blog/item/09dda71ea9d7d21f4134173e.html
我曾经在深入浅出java中文问题
系列中研究过java的中文问题,现在中文问题已经不再羁绊我在java世界中漫游的脚步了。最近,对Python产生了浓厚的兴趣,谁知道跟中文问题这个老朋友又一次不期而遇。看来,在代码世界中,中文问题会在很长一段时间里跟我们形影不离。这也难怪,谁让当初发明计算机的不是我们中国人呢,否则,现在全世界的计算机都支持而且必须支持GBK,这样,写这样文章的人就不会是我了,而是大洋彼岸的一个金发碧眼的程序员,而且标题也相应改为
“studying the english problem in '大蟒' ”。。哈哈
YY而已,还是面对现实问题吧。相对java而言,中文问题在Python中的表现更为激烈。“激烈”的意思不是说更为严重或者说难于解决,只是Python对于decode&encode错误的默认处理方式为strict,也就是直接报错,而java使用replace的方式来处理了,因此java出现中文问题后会打印出很多"??"。此外,Python的默认的encoding是ASCII,而java的默认encoding跟操作系统的encoding是一致的。在这一点上,我觉得java更为合理,这样对程序员更为友好,也减少了newbies
开始时的挫折感,是有利于语言的推广的。但是,Python也有它的道理,毕竟ASCII是唯一的全世界所有平台都支持的字符集,而且问题始终是问题,始终会出现的,逃避它还不如早点面对它。
好了,说了这么多,该说说Python中中文问题的症状了。在这之前,我们先要了解Python中有两种字符串,分别是一般的字符串(每个字符用8
bits表示)和Unicode字符串(每个字符用一个或者多个字节表示),它们可以相互转换。关于Unicode,Joel Spolsky 在 The
Absolute Minimum Every Software Developer Absolutely, Positively Must Know About
Unicode and Character Sets (No Excuses!)
中有生动的说明,Jason Orendorff 在 Unicode for programmers
有着更为全面的描述,在此我就不再多说什么了。来看下面的代码:
x
= u"中文你好"
print s
运行上述代码,Python会给出下面的错误提示
说是遇到非ASCII字符了,并让我们参考pep-0263。PEP-0263(Python Enhancement
Proposal)上面说得很清楚了,Python也意识到了国际化问题,并提出了解决方案。根据提案上面的要求,我们有如下代码 #
-*- coding:gb2312 -*- #必须在第一行或者第二行
print "-------------code
1----------------"
a = "中文a我爱你"
print a
print a.find("我")
b =
a.replace("爱", "喜欢")
print b
print "--------------code
2----------------"
x = "中文a我爱你"
y = unicode(x, "gb2312")
print
y.encode("gb2312")
print y.find(u"我")
z = y.replace(u"爱", u"喜欢")
print
z.encode("gb2312")
print "---------------code 3----------------"
print
y
程序运行的结果如下: -------------code
1----------------
中文a我爱你
5
中文a我喜欢你
--------------code
2----------------
中文a我爱你
3
中文a我喜欢你
---------------code
3----------------
Traceback (most recent call last):
File
"G:\Downloads\eclipse\workspace\p\src\hello.py", line 16, in
<module>
print y
UnicodeEncodeError: 'ascii' codec can't encode
characters in position 0-1: ordinal not in range(128)
我们可以看到,通过引入编码声明,我们可以正常地在使用中文了,而且在code
1和2中,控制台也能正确的把中文打印出来。但是,很明显,上面的代码也反映出了不少的问题:
1、code 1 和
2在使用print时采用了不同的方式,1是直接print,而2在print之前先进行编码
2、code 1 和
2中在同样的字符串查找同一个字符“我”,得出的结果不一样(分别是5和3)
3、code 3 中直接打印unicode字符串
y时出现错误(这也是为什么code 2中要先进行编码的原因)
为什么?为什么?我们可以先在脑海中模拟一下我们使用Python的流程:首先,我们先用编辑器编写好源代码,保存成文件。如果源代码中有编码声明而且用的编辑器支持该语法,那么该文件就以相应的编码方式保存在磁盘中。注意:
编码声明和源文件的编码不一定是一致的,你完全可以在编码声明中声明编码为UTF-8,但是用GB2312来保存源文件。当然,我们不可能自寻烦恼,故意写错,而且好的IDE也能强制保证两者的一致性,但是,如果我们用记事本或者EditPlus等编辑器来编写代码的话,一不小心就会出现这种问题的。
得到一个.py文件后,我们就可以运行它了,这是,我们就把代码交给Python解析器来完成解析工作。解析器读入文件时,先解析文件中的编码声明,我们假设文件的编码为gb2312,那么先将文件中的内容由gb2312转换成Unicode,然后再把这些Unicode转换为UTF-8格式的字节串。完成这一步骤后,解析器把这些UTF-8字节串分段,解析。如果遇到使用Unicode字符串,那么就使用相应的UTF-8字节串创建Unicode字符串,如果程序中使用的是一般的字符串,那么解析器先将UTF-8字节串通过Unicode转换成相应编码(这里就是gb2312编码)的字节串,并用其创建一般的字符串对象。也就是说,Unicode字符串跟一般字符串在内存中的存放格式是不一样的,前者使用UTF-8的格式,后者使用GB2312格式。
好了,内存中的字符串存放格式我们知道了,下面我们要了解print的工作方式。print其实只是负责把内存中相应的字节串交给操作系统,让操作系统相应的程序(譬如cmd窗口)进行显示。这里有两种情况:
1、若字符串是一般的字符串,那么print只需把内存中相应的字节串推送给操作系统。如例子中的code 1。
2、如果字符串是Unicode字符串,那么print在推送之前先进行相应的encode:我们可以显示使用Unicode的encode方法使用合适的编码方式来编码(例子中code
2),否则Python使用默认的编码方式进行编码,也就是ASCII(例子中的code
3)。当然ASCII是不可能正确编码中文的,因此Python报错。
至此,上面的三个问题我们已经可以解析第一和第三个了。至于第二个问题,因为Python中有两种字符串,一般字符串和Unicode字符串,两者都有各自的字符处理方法。对于前者,方法是以字节的方式进行的,而且在GB2312中,每个汉字占用两个字节,因此得到的结果是5;对于后者,也就是Unicode字符串,所有字符都是统一看待的,因此得到3。
虽然上面只提到了控制台程序的中文问题,但是文件读写以及网络传输中出现的中文问题在原理上都是类似的。Unicode的出现可以很大程度上解决软件的国际化问题,同时Python为Unicode提供了极为良好的支持,因此,我建议大家在编写Python的程序时,都统一使用Unicode方式。保存文件时使用UTF-8的编码方式。How
to Use UTF-8 with Python有详细的描述,大家可以参考一下。
Python中能导致出现中文问题的地方还很多,譬如文件的读写,网络数据的传输等,希望大家能多多交流,共同解决这些问题。
|
分享到:
相关推荐
python读取Excel表格的文件,并且把中文转换成英文,然后首字母大写并拼接成@Anqing|安庆|36这种格式,写入txt文件中
python 中文乱码 问题深入分析.docx
Python 中文乱码问题深入分析,理解Python的编码转换方法
programming python 中文第四版
Python学习笔记,Python3.5中文无法显示,可以成功解决
python库的中文参考手册,类似于Java的API文档,可以在里面进行搜索查询等
Python用户手册中文版,适合新手教学
Python拥有一个强大的标准库。Python语言的核心只包含数字、字符串、列表、字典、文件等常见类型和函数,而由Python标准库提供了系统管理、网络通信、文本处理、数据库接口、图形系统、XML处理等额外的功能。Python...
python 3.10.0 官方参考文档 API 完整pdf中文版 python 3.10.0参考文档是一套python官方发布的参考使用文档完整版,包含python安装使用、API参考、常见问题、标准库参考、语言参考、入门教程等,需要的朋友可下载! ...
python 连续拼音转中文,运用到了Pinyin2Hanzi,可以参考一下
python3.8中文帮助文档 离线CHM版 python3.8.chm
python3.10中文使用手册
两本python_opencv中文教程,OpenCV-Python-Toturial-中文版,OpenCV入门教程
这里是 Python 3.9.0 的中文文档。 按章节浏览文档: Python 3.9 有什么新变化? 或显示自 2.0 以来的全部新变化 入门教程 从这里看起 标准库参考 放在枕边作为参考 语言参考 讲解基础内容和基本语法 安装和...
Python3.10官方开发文档(中文版)压缩包解压后,双击打开index.html文件,就能进入文档首页,然后就可以随意访问开发文档,不用再怕python官方网站访问不了了 Python由荷兰数学和计算机科学研究学会的吉多·范罗...
《A Byte of Python》是一本由 Swaroop C H 编写,旨在于介绍如何使用 Python 语言进行编程的自由图书。它以教材与指南的形式为入门者介绍 Python 语言。如果你对电脑知识的了解仅限于如何保存文本文件的话,那这...
Fluent Python 中文版 流畅的Python 适合一定python基础的开发者学习
Python 3.10.4 中文 官方文档,Python 3.10.4 中文 官方文档,Python 3.10.4 中文 官方文档,Python 3.10.4 中文 官方文档,Python 3.10.4 中文 官方文档,Python 3.10.4 中文 官方文档,Python 3.10.4 中文 官方...
sicp in python 中文版 sicp in python 中文版 sicp in python 中文版 !!!download>>>https://github.com/wizardforcel/sicp-py-zh
Head First Python(中文版)面向Python3