布同 Python中文问题解决方法(总结了多位前人经验,初学者必看)


Posted in Python onMarch 13, 2011

因为Python是自带文档,可以通过help函数来查询每一个系统函数的用法解释说明。一般来说,关键的使用方法和注意点在这个系统的文档中都说的很清楚。我试图在网上找过系统文档的中文版的函数功能解释,但是都没有找到,所以我决定将就使用英文版的系统自带的函数解释来学习。

如果你想进行Tkinter和wxPython编程,想要知道一般的widget的使用方法和属性介绍,英文又不是太好的话,我推荐你,你可以去看看《Python与Tkinter编程》这本书,里面392页到538页的附录B和附录C选择了常用的函数和近乎所有的属性进行介绍,精彩不容错过。

我上面提到的这个工具很快做好了。可以把没有查询过的函数进行查询,并保存关键字key和查询结果info,便于下次直接从列表list中翻出来看;要是发现没有查过,则手动添加到列表list——就是这样一个简单的小工具。一切看上去都很顺利。但是问题也来了:英文的info打开后,解释里面有的单词不知道含义,查完单词之后想写在info里面,保存之后可以下次直接从硬盘打开看。但是在英文info中输入中文,保存过程中就出现了解码不了的问题,也就是解码到中文部分就弹出下面这个错误来:

UnicodeEncodeError: 'ascii' codec can't encode character u'\u6211' in position 61: ordinal not in range(128)

其中的61这个位置是弹性的,就是info中加入了中文的那个位置。这个错误基本一直都存在,也就是当我想要把修改过后的info写入文件的时候:

fp = open('tt.txt','w') 

fp.write(info.encode("UTF-8")) # 此处错误 

fp.close()

这三行本身看上去没有错误。但是就是在中间这行代码处出现了错误。难道是encode的方式不对?我有尝试了很多种编码,如ANSI、UTF-8、SHIFT_JIS、GB2312、GBK等编码,发现都不行。于是我就糊涂了。

现在我已经知道为什么错误了。问题就在于修改之后的info这个字符串变量。info中的数据是我从系统中通过help函数查到的字串(也就是原始的纯英文的info)加上我手动输入的中文得到的一个综合的字符串。在我从系统中查询系统文档时,我对原始info进行了如下保存:

fp = open('tt.txt','w') 

fp.write(info) 

fp.close()

注意,错就错在直接将原始info直接写入到文件中。这样写之后的编码方式大家知道是什么吗?你打开tt.txt,查看编码方式将会知道,其编码方式是ANSI格式。于是错误就是这样产生的:我查询关键字key,将这个ANSI格式的字串info读到控件中显示,然后我有手动的添加了UTF-8格式的中文字符,于是通连起来形成的字符串info,就是一个混乱而具有多种编码方式的字符串info,系统怎么write都无法只使用一种编码方式将这个混合字串info再次写到tt.txt中去。

所以,结论就是:当你在内存中操作时,你可以随意的不管编码方式是什么,系统会自动的按照具体情况进行判断。但是你如果要用到中文字符,并且还要通过文件的方式去暂时保存数据或者字串的话,请你一定要在第一次写文件的时候用utf-8的格式写进去,也就是如下的方式:

fp = open('tt.txt','w') 
fp.write(info.encode("UTF-8")) 
fp.close()

这将会保证你下次读出来之后不用转换编码方式就可以直接打印和显示,即使是作为控件文本也没有问题。一定要注意这一点。

问题找到了,下面进行一些其他的讨论。

有的人说,只要使用了# -*- coding:utf-8 -*-不就行了吗?其实不然。

通过我的测试(我使用IDLE(Python2.5.4 GUI)编译器。【1】无论我开头用不用# -*- coding:utf-8 -*-,还是软件中是不是设置了使用默认的utf-8编码方式,中文在控件和文件之间的使用都是没有问题的。【2】info='中文'; 这样的操作都是可以的。读的时候使用一般的读法就可以了。原因我想是因为编译器升级,解决了中文显示和使用的问题,早期中文语言不能够使用的情况现在已经不存在了。

#coding=utf-8 
try: 
JAP=open("jap.txt","r") 
CHN=open("chn.txt","r") 
UTF=open("utf.txt","w") 

jap_text=JAP.readline() 
chn_text=CHN.readline() 
#先decode成UTF-16,再encode成UTF-8 
jap_text_utf8=jap_text.decode("SHIFT_JIS").encode("UTF-8") 
#不转成utf-8也可以 
chn_text_utf8=chn_text.decode("GB2312").encode("UTF-8") 
#编码方式大小写都行utf-8也一样 
UTF.write(jap_text_utf8) 
UTF.write(chn_text_utf8) 
UTF.close() 
except IOError,e: 
print "open file error",e

这是我从//3water.com/article/26542.htm中《学习python处理python编码》文章中摘录的代码。这里做一下解释,上面的jap_text_utf8和chn_text_utf8都要保证是机器默认的编码方式,或者utf-8编码方式,最重要的就是要保持一致。通过统一的编码为utf-8后,就可以写入一个文件中,再次读出使用都没有问题。读的时候使用下面的普通方式即可:

filen = open('tt.txt') 

info = filen.read() 

print info

另外。有人使用了下面这种方式来编码和转换:
import sys 
reload(sys) 
sys.setdefaultencoding('utf8') 

def ConvertCN(s): 
return s.encode('gb18030') 

def PrintFile(filename): 
f = file(filename, 'r') 
for f_line in f.readlines(): 
print ConvertCN(f_line) 
f.close() 

if __name__ == "__main__": 
PrintFile('1.txt') 
print ConvertCN("\n****** 按任意键退出! ******") 
print sys.stdin.readline()

通过我的测试,这种方式是不可行的。第二行如果去掉,第三行的setdefaultencoding函数将会无效;如果保留第二行,第三行和以后的代码都得不到执行(虽然不报错)。这种方式是否可行请大家试试看。

 

另外,《python 中文乱码 问题深入分析》//3water.com/article/26543.htm一文中讲到了很多文本如何编码的问题,令我大开眼界。文本编码的原理:原来就是在文本开头处添加适当的注释符号来表示内部的编码方式,于是解释器就会以某种对应的规则去按照某种步长的字节或者灵活的方式去翻译字节,得到原文,翻译的步长和规则完全是开头的说明处对应的。所以,如果你正文是单个字节的编码方式,那么你就可以在你的编码最前头加上一个合适的规则,告诉别人如何翻译你的被编码文本即可。其中BOM_UTF_8等文本末尾的知识也是很有趣的,类似的还有BOM_UTF_16等等,不同的编码方式文末的符号不同,大家可以注意一下。

Python 相关文章推荐
Python中input和raw_input的一点区别
Oct 21 Python
python刷投票的脚本实现代码
Nov 08 Python
Python中IPYTHON入门实例
May 11 Python
python中pandas.DataFrame对行与列求和及添加新行与列示例
Mar 12 Python
使用python脚本实现查询火车票工具
Jul 19 Python
Linux 修改Python命令的方法示例
Dec 03 Python
对python 命令的-u参数详解
Dec 03 Python
python+opencv实现霍夫变换检测直线
Oct 23 Python
使用Python向DataFrame中指定位置添加一列或多列的方法
Jan 29 Python
Django+Xadmin构建项目的方法步骤
Mar 06 Python
python实现批量视频分帧、保存视频帧
May 31 Python
pyqt5 QScrollArea设置在自定义侧(任何位置)
Sep 25 Python
布同 统计英文单词的个数的python代码
Mar 13 #Python
python将多个文本文件合并为一个文本的代码(便于搜索)
Mar 13 #Python
布同自制Python函数帮助查询小工具
Mar 13 #Python
Python中的文件和目录操作实现代码
Mar 13 #Python
python 中的列表解析和生成表达式
Mar 10 #Python
Python中使用中文的方法
Feb 19 #Python
python实现的防DDoS脚本
Feb 08 #Python
You might like
PHP函数utf8转gb2312编码
2006/12/21 PHP
WordPress迁移时一些常见问题的解决方法整理
2015/11/24 PHP
php提交post数组参数实例分析
2015/12/17 PHP
PHP身份证校验码计算方法
2016/08/10 PHP
php+Memcached实现简单留言板功能示例
2017/02/15 PHP
php操作mongodb封装类与用法实例
2018/09/01 PHP
Document对象内容集合(比较全)
2010/09/06 Javascript
juqery 学习之四 筛选查找
2010/11/30 Javascript
Javascript 中 null、NaN和undefined的区别总结
2013/04/10 Javascript
JavaScript中的函数嵌套使用
2015/06/04 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
Javascript Event(事件)的传播与冒泡
2017/01/23 Javascript
js return返回多个值,通过对象的属性访问方法
2017/02/21 Javascript
基于Vue实现tab栏切换内容不断实时刷新数据功能
2017/04/13 Javascript
Nodejs实现多房间简易聊天室功能
2017/06/20 NodeJs
详解vue.js之绑定class和style的示例代码
2017/08/24 Javascript
Vue v2.4中新增的$attrs及$listeners属性使用教程
2018/01/08 Javascript
微信小程序之swiper轮播图中的图片自适应高度的方法
2018/04/23 Javascript
Vue刷新修改页面中数据的方法
2018/09/16 Javascript
解决mui框架中switch开关通过js控制开或者关状态时小圆点不动的问题
2019/09/03 Javascript
基于脚手架创建Vue项目实现步骤详解
2020/08/03 Javascript
如何使用gpu.js改善JavaScript的性能
2020/12/01 Javascript
Python脚本文件打包成可执行文件的方法
2015/06/02 Python
Python实现把json格式转换成文本或sql文件
2015/07/10 Python
Python实现的特征提取操作示例
2018/12/03 Python
python感知机实现代码
2019/01/18 Python
python可视化篇之流式数据监控的实现
2019/08/07 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
2019/12/11 Python
python中resample函数实现重采样和降采样代码
2020/02/25 Python
python小白学习包管理器pip安装
2020/06/09 Python
HTML高亮关键字的实现代码
2018/10/22 HTML / CSS
英国领先的品牌珠宝和配件供应商:Acotis Jewellery
2018/03/07 全球购物
电子商务应届生求职信
2013/11/16 职场文书
劳动竞赛口号
2014/06/16 职场文书
关于迟到的检讨书
2015/05/06 职场文书
Java Dubbo框架知识点梳理
2021/06/26 Java/Android