布同 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装饰器 免去调用父类构造函数的麻烦
May 18 Python
Python实现按照指定要求逆序输出一个数字的方法
Apr 19 Python
详解pandas的外部数据导入与常用方法
May 01 Python
pybind11在Windows下的使用教程
Jul 04 Python
django admin.py 外键,反向查询的实例
Jul 26 Python
pytorch masked_fill报错的解决
Feb 18 Python
python利用Excel读取和存储测试数据完成接口自动化教程
Apr 30 Python
如何对python的字典进行排序
Jun 19 Python
用Python制作音乐海报
Jan 26 Python
python 爬取华为应用市场评论
May 29 Python
Django实现drf搜索过滤和排序过滤
Jun 21 Python
python人工智能human learn绘图可创建机器学习模型
Nov 23 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数学运算函数大汇总(经典值得收藏)
2016/04/01 PHP
PHP简单实现二维数组赋值与遍历功能示例
2017/10/19 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
JS 无法通过W3C验证的处理方法
2010/03/09 Javascript
Uglifyjs(JS代码优化工具)入门 安装使用
2020/04/13 Javascript
轻松创建nodejs服务器(7):阻塞操作的实现
2014/12/18 NodeJs
jQuery超精致图片轮播幻灯片特效代码分享
2015/09/10 Javascript
Jquery1.9.1源码分析系列(六)延时对象应用之jQuery.ready
2015/11/24 Javascript
JavaScript+Java实现HTML页面转为PDF文件保存的方法
2016/05/30 Javascript
jQuery实现的选择商品飞入文本框动画效果完整实例
2016/08/10 Javascript
js实现固定宽高滑动轮播图效果
2017/01/13 Javascript
微信小程序中吸底按钮适配iPhone X方案
2017/11/29 Javascript
webpack热模块替换(HMR)/热更新的方法
2018/04/05 Javascript
详解js类型判断
2018/05/22 Javascript
说说node中的可读流和可写流的区别
2018/06/01 Javascript
Vue 框架之键盘事件、健值修饰符、双向数据绑定
2018/11/14 Javascript
angular组件间传值测试的方法详解
2020/05/07 Javascript
antd Form组件方法getFieldsValue获取自定义组件的值操作
2020/10/29 Javascript
js+html+css实现手动轮播和自动轮播
2020/12/30 Javascript
[03:54]DOTA2英雄梦之声_第06期_昆卡
2014/06/23 DOTA
Python标准库之sqlite3使用实例
2014/11/25 Python
Python中下划线的使用方法
2015/03/27 Python
解决pandas 作图无法显示中文的问题
2018/05/24 Python
使用SQLAlchemy操作数据库表过程解析
2020/06/10 Python
windows10在visual studio2019下配置使用openCV4.3.0
2020/07/14 Python
Python基于爬虫实现全网搜索并下载音乐
2021/02/14 Python
CSS3 RGBA色彩模式使用实例讲解
2016/04/26 HTML / CSS
巴西最大的在线约会网站:ParPerfeito
2018/07/11 全球购物
三星新西兰官网:Samsung新西兰
2019/03/05 全球购物
学生会竞聘书范文
2014/03/31 职场文书
国家税务局干部作风整顿整改措施
2014/09/18 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
2014年客户经理工作总结
2014/11/20 职场文书
领导欢迎词范文
2015/01/26 职场文书
公司2015年终工作总结
2015/05/26 职场文书
Pandas搭配lambda组合使用详解
2022/01/22 Python