`
fyting
  • 浏览: 217119 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

python编码问题和i18n

阅读更多

初学Python,遇到很多编码问题,记下来以免将来又忘了,很多东西不懂,都是属于不求甚解,乱下结论,但想到拿出来可以有热心同学指出错误所在,便厚起脸皮了……
首先需要了解Python中有两种字符串(严格地说,似乎不能这么叫)。一种是普通的str对象(每个字符用8bits表示),另一种是unicode字符串,它们可以相互转换。
首先打开pyshell,输入一段代码。

python 代码
 
  1. >>> a = "我"   
  2. >>> b = unicode(a,"gb2312")   
  3. >>> a.__class__   
  4. <type 'str'>   
  5. >>> b.__class__   
  6. <type 'unicode'>   
  7. >>>    

看出来了吧,两种字符串。
再来

python 代码
  1. >>> a   
  2. '\xce\xd2'   
  3. >>> b   
  4. u'\u6211'  

变量a是两个字符,b是一个unicode字符。
关于这两种字符串,Python文档-->LanguageReference-->DataModel-->The standard type hierarchy-->Sequences,有一些Strings,Unicode的描述。
至于

python 代码
 
  1. >>> z = u"我"   
  2. >>> #这种代码,其实什么都不是。   
  3. >>> z.__class__   
  4. <type 'unicode'>   
  5. >>> z   
  6. 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 代码
 
  1. >>> a.decode("gb2312")   
  2. u'\u6211'   
  3. >>> print a.decode("gb2312")   
  4. 我   
  5. >>> a.encode("gb2312")   
  6. Traceback (most recent call last):   
  7.   File "<input>", line 1, in ?   
  8. UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)  

b是unicode类型,打印时需要先encode(编码)成系统编码

python 代码
 
  1. >>> print b.encode("gb2312")   
  2. 我   
  3. >>> b.encode("gb2312")   
  4. '\xce\xd2'   
  5. >>> b.decode("gb2312")   
  6. Traceback (most recent call last):   
  7.   File "<input>", line 1, in ?   
  8. 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 代码
 
  1. >>> sql = "INSERT INTO t_user(name,nickname) values(%s,%s)"   
  2. >>> param = ("张三","张三的昵称")   
  3. >>> 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 代码
 
  1. import gettext   
  2. gettext.install('i18ntest', './locale', unicode=True)  

参数说明:
作用域:用于限定翻译文件的主名
路径:翻译文件所在路径
unicode:使用unicode

2.把代码里需要国际化的文本全部使用_("text")的形式进行替换

3.需要进行国际化处理时,调用

python 代码
 
  1. 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

  • i18n.zip (22.5 KB)
  • 描述: 18n的一个例子,从RecipesI18n改的
  • 下载次数: 49
分享到:
评论
1 楼 simohayha 2007-03-30  
呵呵,这篇文章也加到python圈子吧?

相关推荐

    python-precis-i18n

    在深入探讨Python-precis-i18n之前,我们先理解一下国际化(i18n)和PRECIS的基本概念: **国际化(i18n)**:这是一个软件设计过程,使软件能够适应不同地区的语言、文化和社会习惯。这通常涉及到文本的本地化、日期和...

    i18N

    - 许多编程语言提供了专门的库或框架,如Java的Java Internationalization API (Java i18n),JavaScript的i18next,以及Python的gettext等,来简化国际化过程。 10. **设计原则**: - 设计阶段就要考虑国际化,...

    i18n.pdf

    3. 文本编码与字符集:考虑到全球各地语言的多样性,i18n需要支持多种字符集,如Unicode,以确保所有语言都能正确显示。 4. 日期和时间格式:不同的国家和地区有不同的日期和时间表示方式,i18n需要提供机制来自动...

    PyPI 官网下载 | precis_i18n-0.4.1-py3-none-any.whl

    总之,"precis_i18n"是Python开发者在处理国际化问题时的一个强大工具,它简化了不同语言字符串的处理,提高了代码的可维护性和应用的全球适用性。通过从PyPI官网下载并安装"precis_i18n-0.4.1-py3-none-any.whl",...

    eric5-i18n-zh_CN.GB2312-5.5.1.zip

    综上所述,"eric5-i18n-zh_CN.GB2312-5.5.1.zip"这个文件是专为中国用户设计的Python IDE Eric5的5.5.1版本,它支持中文界面并使用了GB2312编码,体现了软件国际化的重要性和对中文环境的适应性。对于使用中文环境的...

    Python库 | zope.i18nmessageid-4.0.1.tar.gz

    在Python的世界里,国际化(i18n)与本地化(l10n)是开发跨语言应用的重要环节,使得软件能够适应全球不同地区的用户。`zope.i18nmessageid`是一个针对这一需求的Python库,专门用于处理国际化消息标识,它在4.0.1...

    Go-Packagei18n为Macaron提供软件国际化和本地化

    在Go语言中,开发Web应用时经常会遇到需要支持多语言环境的情况,这涉及到软件的国际化(i18n)和本地化(l10n)。"Go-Package i18n"是一个专门针对Macaron框架设计的库,它帮助开发者轻松实现这一功能。Macaron是一个轻...

    eric5-i18n-zh_CN.GB2312-5.1.2.zip

    总结来说,"eric5-i18n-zh_CN.GB2312-5.1.2.zip"是一个针对Eric5 5.1.2版本的中文汉化包,使用GB2312编码,为中国的Python开发者提供了一个更符合本土习惯的开发环境。理解和正确应用此类汉化包,对于提升中国用户的...

    i18-demo

    5. **编程语言实现**:可能涵盖了使用特定编程语言(如Java、JavaScript、Python等)实现i18n的技巧和库,比如Java的ResourceBundle,JavaScript的i18next库等。 6. **测试与调试**:讨论如何确保所有语言版本的...

    i18.rar 国际化

    国际化(i18n)是软件开发中的一个重要概念,它是指设计和实现一个软件系统,使其能够适应不同的语言和文化环境。"i18"这个缩写来自于“internationalization”,其中18代表了单词“internationalization”中字母的...

    I18N-LHC

    在这个上下文中,I18N通常指的是软件开发中的一个过程,使得产品能够适应不同国家和地区的语言及文化需求,而LHC则是一个物理实验设施,位于欧洲核子研究组织(CERN)的瑞士和法国边境,主要用于高能粒子物理的研究...

    PyPI 官网下载 | infrae.i18nextract-1.0.tar.gz

    这个库主要服务于Python应用的国际化(i18n)和本地化(l10n)处理,使得开发者能够轻松地为不同地区的用户提供符合他们语言习惯的服务。 国际化(i18n)和本地化(l10n)是软件开发中的关键概念,尤其是对于那些目标用户...

    localization:Paymo i18n

    为了实现Paymo的i18n和L10n,开发者可能采用了以下技术策略: 1. **分离业务逻辑和用户界面**:将程序代码与界面文本分离,使翻译工作更容易进行。 2. **使用国际化框架**:比如Java的Resource Bundle,JavaScript...

    CodingProblems_Python:Python中的编码问题供面试和练习

    8. **国际化与本地化**: Python的`locale`模块可以帮助处理不同地区的语言和字符集,实现国际化(i18n)和本地化(l10n)功能。 9. **第三方库支持**: `chardet`库可以帮助检测未知的编码格式,`unidecode`库可以将...

    python-3.11.5-docs-pdf-a4.zip

    - **i18n 改进**:Python 3.11 可能改进了国际化的支持,简化多语言应用的开发。 8. **开发者工具**: - **pip 升级**:Python 的包管理器 `pip` 可能有新的特性或性能提升。 - **虚拟环境管理**:`venv` 或 `...

    PyPI 官网下载 | zope.i18nmessageid-3.4.3-py2.6-win-amd64.egg

    zope.i18nmessageid是Zope国际化(i18n)框架的一部分,主要处理消息标识(message ID)。在软件本地化(l10n)中,消息标识用于唯一地标识需要翻译的文本片段。该库提供了一种机制,使得开发者可以将程序中的字符串与它们...

    python3.9lib

    - `gettext`: 提供国际化(i18n)和本地化(l10n)支持。 9. **并发和多线程模块**: - `threading`: 支持多线程编程,提供线程、锁、事件等对象。 - `concurrent.futures`: 提供一个高级接口来异步执行可调用...

    discord-translator-i18n:Discord Translator bot的本地化项目-Discord最强大的翻译bot

    1. **i18n** - 表明项目的核心是国际化,即软件设计允许容易扩展到全球不同的语言和地区。 2. **bot** - 指出这是一个自动化程序,即Discord上的聊天机器人,能够自动响应用户请求并执行任务,如翻译。 3. **...

Global site tag (gtag.js) - Google Analytics