python编码问题
2009-06-19 15:48
357 查看
初学Python,遇到很多编码问题,记下来以免将来又忘了,很多东西不懂,都是属于不求甚解,乱下结论,但想到拿出来可以有热心同学指出错误所在,便厚起脸皮了……
首先需要了解Python中有两种字符串(严格地说,似乎不能这么叫)。一种是普通的str对象(每个字符用8bits表示),另一种是unicode字符串,它们可以相互转换。
首先打开pyshell,输入一段代码。
python 代码
看出来了吧,两种字符串。
再来
python 代码
变量a是两个字符,b是一个unicode字符。
关于这两种字符串,Python文档-->LanguageReference-->DataModel-->The standard type hierarchy-->Sequences,有一些Strings,Unicode的描述。
至于
python 代码
看到了吧,这个奇怪的东西......
后来在WindowsXP、纯python命令行下试过,得出的结论不同,z的结果变成了u'/u6211',这里完全不应该在pyshell下作试验的,看来还有很多问题尚未理解清楚
再来看看encode,decode
什么情况用encode,什么情况又是decode呢,刚开始总是被搞昏。其实各种本地字符集的英文名是Coded Character Set,要转换为Coded,肯定是要encode了,同样,从里面解出来也应该叫decode……
decode就是把其他编码转换为unicode,等同于unicode函数;encode就是把unicode编码的字符串转换为特定编码。在pyshell里继续:
a是Str类型的,所以再用encode会报错。用print输出时会调用默认编码转换为系统编码?
python 代码
b是unicode类型,打印时需要先encode(编码)成系统编码
python 代码
python里默认的encode和decode是strict模式,所以会直接抛出Error,而Java里是默认replace模式,所以在处理servlet时经常会看到一串?????
在decode时传入第二个参数errors为'replace'可以和Java相同,但总是没成功,还不知道为什么
MySQLDb连接数据库的编码问题
试了很久,无论在connect的时候指定charset='utf8',还是使用set_character_set(),或者执行"SET NAMES UTF8",跟踪到character_set_name()方法返回的都是latin1...再跟代码,似乎就跑到mysql-api里去了,反正最后解决的办法也很简单,就是使用如下方式执行,而不要去拼sql语句……
python 代码
Python的国际化/i18n问题
使用gettext来实现。其实就是一个文本替换的方式,和java里用ResourceBundle、properties比较类似…… http://wiki.wxpython.org/index.cgi/RecipesI18n有一个recipe,不过代码很旧了,现在python里自带了pygettext.py和msgfmt.py 其实就是把http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx的文章按自己思路组织了一下。
步骤:
1.导入gettext模块
python 代码
参数说明:
作用域:用于限定翻译文件的主名
路径:翻译文件所在路径
unicode:使用unicode
2.把代码里需要国际化的文本全部使用_("text")的形式进行替换
3.需要进行国际化处理时,调用
python 代码
来处理。
现在程序写好了,需要生成所需资源文件了:
1.调用python安装目录的 Tools/i18n/pygettext.py抽取所需翻译的模板
>>> pygettext.py path/to/yourfile.py
将生成一个名为messages.pot的文件
2.生成模板文件后,修改这个模板文件,其中的msgid为键值,对应你程序里写的文本,如:_("New File"),而msgstr为翻译后的值。还有就是注意修改文件头部分Content-Type的charset为合适的编码,比如utf8
3.编写好模板后,把扩展名修改为.po,运行Tools/i18n/msgfmt.py,生成二进制的资源文件
>>> msgfmt.py messages.po
将生成一个名为messages.mo的文件
4.把这个mo文件放在正确的位置.
比如你在程序中是这样写的:
gettext.install('i18ntest', './locale', unicode=True)
gettext.translation('i18ntest', './locale', languages=['cn']).install(True)
那么你的程序目录下需要存在./local/cn/LC_MESSAGES/i18ntest.mo
这样程序启动时就会读取这个资源文件,替换对应的文本,实现国际化了。
注意:如果使用utf格式保存,po文件不能有BOM头。cn目录是所对应的语言,LC_MESSAGES目录是gettext.py里要求的,mo文件必须和所定义的域同名,见
gettext.py的mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
学习资料
All About Python and Unicode http://boodebr.org/main/python/all-about-python-and-unicode
彻底了解python的编码问题 http://blog.csdn.net/iamjianglibo/archive/2007/02/07/1504819.aspx
Python中文问题研究 http://hi.baidu.com/daping_zhang/blog/item/09dda71ea9d7d21f4134173e.html
MySQLdb带中文参数的问题 http://bbs.chinaunix.net/archiver/?tid-833164.html
wxPython RecipesI18n http://wiki.wxpython.org/index.cgi/RecipesI18n
limodou的blog和ulipad/doc/i18n.htm
http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx
http://blog.donews.com/limodou/archive/2004/06/15/28947.aspx
http://blog.donews.com/limodou/archive/2004/06/15/28961.aspx
首先需要了解Python中有两种字符串(严格地说,似乎不能这么叫)。一种是普通的str对象(每个字符用8bits表示),另一种是unicode字符串,它们可以相互转换。
首先打开pyshell,输入一段代码。
python 代码
>>> a = "我" >>> b = unicode(a,"gb2312") >>> a.__class__ <type 'str'> >>> b.__class__ <type 'unicode'> >>>
看出来了吧,两种字符串。
再来
python 代码
>>> a '/xce/xd2' >>> b u'/u6211'
变量a是两个字符,b是一个unicode字符。
关于这两种字符串,Python文档-->LanguageReference-->DataModel-->The standard type hierarchy-->Sequences,有一些Strings,Unicode的描述。
至于
python 代码
>>> z = u"我" >>> #这种代码,其实什么都不是。 >>> z.__class__ <type 'unicode'> >>> z u'/xce/xd2'
看到了吧,这个奇怪的东西......
后来在WindowsXP、纯python命令行下试过,得出的结论不同,z的结果变成了u'/u6211',这里完全不应该在pyshell下作试验的,看来还有很多问题尚未理解清楚
再来看看encode,decode
什么情况用encode,什么情况又是decode呢,刚开始总是被搞昏。其实各种本地字符集的英文名是Coded Character Set,要转换为Coded,肯定是要encode了,同样,从里面解出来也应该叫decode……
decode就是把其他编码转换为unicode,等同于unicode函数;encode就是把unicode编码的字符串转换为特定编码。在pyshell里继续:
a是Str类型的,所以再用encode会报错。用print输出时会调用默认编码转换为系统编码?
python 代码
>>> a.decode("gb2312") u'/u6211' >>> print a.decode("gb2312") 我 >>> a.encode("gb2312") Traceback (most recent call last): File "<input>", line 1, in ? UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
b是unicode类型,打印时需要先encode(编码)成系统编码
python 代码
>>> print b.encode("gb2312") 我 >>> b.encode("gb2312") '/xce/xd2' >>> b.decode("gb2312") Traceback (most recent call last): File "<input>", line 1, in ? UnicodeEncodeError: 'ascii' codec can't encode character u'/u6211' in position 0: ordinal not in range(128)
python里默认的encode和decode是strict模式,所以会直接抛出Error,而Java里是默认replace模式,所以在处理servlet时经常会看到一串?????
在decode时传入第二个参数errors为'replace'可以和Java相同,但总是没成功,还不知道为什么
MySQLDb连接数据库的编码问题
试了很久,无论在connect的时候指定charset='utf8',还是使用set_character_set(),或者执行"SET NAMES UTF8",跟踪到character_set_name()方法返回的都是latin1...再跟代码,似乎就跑到mysql-api里去了,反正最后解决的办法也很简单,就是使用如下方式执行,而不要去拼sql语句……
python 代码
>>> sql = "INSERT INTO t_user(name,nickname) values(%s,%s)" >>> param = ("张三","张三的昵称") >>> cursor.execute(sql,param)
Python的国际化/i18n问题
使用gettext来实现。其实就是一个文本替换的方式,和java里用ResourceBundle、properties比较类似…… http://wiki.wxpython.org/index.cgi/RecipesI18n有一个recipe,不过代码很旧了,现在python里自带了pygettext.py和msgfmt.py 其实就是把http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx的文章按自己思路组织了一下。
步骤:
1.导入gettext模块
python 代码
import gettext gettext.install('i18ntest', './locale', unicode=True)
参数说明:
作用域:用于限定翻译文件的主名
路径:翻译文件所在路径
unicode:使用unicode
2.把代码里需要国际化的文本全部使用_("text")的形式进行替换
3.需要进行国际化处理时,调用
python 代码
gettext.translation('i18ntest', './locale', languages=['cn']).install(True)
来处理。
现在程序写好了,需要生成所需资源文件了:
1.调用python安装目录的 Tools/i18n/pygettext.py抽取所需翻译的模板
>>> pygettext.py path/to/yourfile.py
将生成一个名为messages.pot的文件
2.生成模板文件后,修改这个模板文件,其中的msgid为键值,对应你程序里写的文本,如:_("New File"),而msgstr为翻译后的值。还有就是注意修改文件头部分Content-Type的charset为合适的编码,比如utf8
3.编写好模板后,把扩展名修改为.po,运行Tools/i18n/msgfmt.py,生成二进制的资源文件
>>> msgfmt.py messages.po
将生成一个名为messages.mo的文件
4.把这个mo文件放在正确的位置.
比如你在程序中是这样写的:
gettext.install('i18ntest', './locale', unicode=True)
gettext.translation('i18ntest', './locale', languages=['cn']).install(True)
那么你的程序目录下需要存在./local/cn/LC_MESSAGES/i18ntest.mo
这样程序启动时就会读取这个资源文件,替换对应的文本,实现国际化了。
注意:如果使用utf格式保存,po文件不能有BOM头。cn目录是所对应的语言,LC_MESSAGES目录是gettext.py里要求的,mo文件必须和所定义的域同名,见
gettext.py的mofile = os.path.join(localedir, lang, 'LC_MESSAGES', '%s.mo' % domain)
学习资料
All About Python and Unicode http://boodebr.org/main/python/all-about-python-and-unicode
彻底了解python的编码问题 http://blog.csdn.net/iamjianglibo/archive/2007/02/07/1504819.aspx
Python中文问题研究 http://hi.baidu.com/daping_zhang/blog/item/09dda71ea9d7d21f4134173e.html
MySQLdb带中文参数的问题 http://bbs.chinaunix.net/archiver/?tid-833164.html
wxPython RecipesI18n http://wiki.wxpython.org/index.cgi/RecipesI18n
limodou的blog和ulipad/doc/i18n.htm
http://blog.donews.com/limodou/archive/2004/06/15/28916.aspx
http://blog.donews.com/limodou/archive/2004/06/15/28947.aspx
http://blog.donews.com/limodou/archive/2004/06/15/28961.aspx
相关文章推荐
- python转载[编码问题]
- 由__future__中unicode_literals引起的错误来研究python中的编码问题
- Python3 将信息写入txt文件时的编码问题 ™
- [Python]编码问题
- 学习python处理python编码问题
- Python中文编码问题
- python2.7编码问题
- 初步解决python编码问题
- python2.7中编码问题以及txt文件读写的注意事项
- 解决python with 在写入文件是因编码格式不同而造成乱码问题
- 搞定Python编码问题
- Python资料之编码问题
- python 处理movie-review-data遇到的UnicodeDecodeError 编码问题
- python编码问题(1)
- sublime python3中读取和写入文件时如何解决编码问题
- python中文编码问题
- python文件操作编码问题
- python 编码编码相关问题
- python 在 eclipse 上的编码配置问题
- 学习笔记第四篇之python编码问题