sharplife


software is a artwork, also make the life better !!!
  首页 :: 联系 :: 订阅 订阅 :: 管理

公告

Python 2.x Unicode 简记

Posted on 2009-03-07 18:47 sharplife 阅读(...) 评论(...) 编辑 收藏

1、Python & Unicode (《Dive into python》)

例 9.13. unicode 介绍

>>> s = u'Dive in'            1
>>> s
u'Dive in'
>>> print s 2
Dive in
1 为了创建一个 unicode 字符串而不是通常的 ASCII 字符串,要在字符串前面加上字母 “u”。注意这个特殊的字符串没有任何非 ASCII 的字符。这样很好;unicode 是 ASCII 的一个超集 (一个非常大的超集),所以任何正常的 ASCII 都可以以 unicode 形式保存起来。
2 在打印字符串时,Python 试图将字符串转换为你的默认编码,通常是 ASCII(过会儿有更详细的说明。) 因为组成这个 unicode 字符串的字符都是 ASCII 字符,打印结果与打印正常的 ASCII 字符串是一样的;转换是无缝的,而且如果你没有注意到 s 是一个 unicode 字符串的话,你永远也不会注意到两者之间的差别。

例 9.14. 存储非 ASCII 字符

>>> s = u'La Pe\xf1a'         1
>>> print s 2
Traceback (innermost last):
File "<interactive input>", line 1, in ?
UnicodeError: ASCII encoding error: ordinal not in range(128)

>>> print s.encode('latin-1') 3
La Peña
1 unicode 真正的优势,理所当然的是它保存非 ASCII 字符的能力,例如西班牙语的 “ñ”(n 上带有一个波浪线)。用来表示波浪线 n 的 unicode 字符编码是十六进制的 0xf1 (十进制的241),你可以像这样输入:\xf1
2 还记得我说过 print 函数会尝试将 unicode 字符串转换为 ASCII 从而打印它吗?嗯,在这里将不会起作用,因为你的 unicode 字符串包含非 ASCII 字符,所以 Python 会引发 UnicodeError 异常。
3 这儿就是将 unicode 转换为其它编码模式起作用的地方。s 是一个 unicode 字符串,但 print 只能打印正常的字符串。为了解决这个问题,我们调用 encode 方法 (它可以用于每个 unicode 字符串) 将 unicode 字符串转换为指定编码模式的正常字符串。我们向此函数传入一个参数。在本例中,我们使用 latin-1 (也叫 iso-8859-1),它包括带波浪线的 n (然而缺省的 ASCII 编码模式不包括,因为它只包含数值从 0 到 127 的字符)。

还记得我说过:需要从一个 unicode 得到一个正常字符串时,Python 通常默认将 unicode 转换成 ASCII 吗?嗯,这个默认编码模式是一个可以定制的选项。

例 9.15. sitecustomize.py

# sitecustomize.py                   1
# this file can be anywhere in your Python path,
# but it usually goes in ${pythondir}/lib/site-packages/
import sys
sys.setdefaultencoding('iso-8859-1') 2
1 sitecustomize.py 是一个特殊的脚本;Python 会在启动的时候导入它,所以在其中的任何代码都将自动运行。就像注解中提到的那样,它可以放在任何地方 (只要 import 能够找到它),但是通常它位于 Pythonlibsite-packages 目录中。 
2 嗯,setdefaultencoding 函数设置默认编码。Python 会在任何需要将 unicode 字符串自动转换为正规字符串的地方,使用这个编码模式。

例 9.16. 设置默认编码的效果

>>> import sys
>>> sys.getdefaultencoding() 1
'iso-8859-1'
>>> s = u'La Pe\xf1a'
>>> print s 2
La Peña
1 这个例子假设你已经按前一个例子中的改动对 sitecustomize.py 文件做了修改,并且已经重启了 Python。如果你的默认编码还是 'ascii',可能你就没有正确设置 sitecustomize.py 文件,或者是没有重新启动 Python。默认的编码只能在 Python 启动的时候改变;之后就不能改变了。(由于一些我们现在不会仔细研究的古怪的编程技巧,你甚至不能在 Python 启动之后调用 sys.setdefaultencoding 函数。仔细研究 site.py,并搜索 “setdefaultencoding” 去发现为什么吧。)
2 现在默认的编码模式已经包含了你在字符串中使用的所有字符,Python 对字符串的自动强制转换和打印就不存在问题了。

例 9.17. 指定.py文件的编码

如果你打算在你的 Python 代码中保存非 ASCII 字符串,你需要在每个文件的顶端加入编码声明来指定每个 .py 文件的编码。这个声明定义了 .py 文件的编码为 UTF-8:

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

现在,想想 XML 中的编码应该是怎样的呢?不错,每一个 XML 文档都有指定的编码。重复一下,ISO-8859-1 是西欧语言存放数据的流行编码方式。KOI8-R 是俄语流行的编码方式。编码――如果指定了的话――都在 XML 文档的首部。

2、Python正则表达式

有了上面的基础,实践一个小应用问题的解决,用python正则表达式取匹配串(当然包含中文了)

仅英文情况下(ASCII),下面的代码是可以的,test.py(文件编码为默认)

Code
import re
p
=r'\$([^\$\s]+)'
s
=u'dsd$dd$111'
m
=re.findall(p,s)
print m

output: [u
'dd', u'111']

当字符串s中有中文时,须如下方可,test1.py(文件编码也是utf-8)

Code
#!/usr/bin/python
#
 -*- coding:utf-8 -*-

import re
p
=r'\$([^\$\s]+)'
s
=u'dsd$哈哈哈$大苏打'
m
=re.findall(p,s)
print m

# output: [u
'\u4f60\u7684\u601d\u5ff5', u'\u5927\u82cf\u6253\u6492']
#没显示成中文缘于win cmd对unicode的支持,下面的方式可以令其显示中文

for i in m:
    print i.encode('GBK')
# output:你的思念 
大苏打
# cmd shell支持gbk,且上述中文字符有属于gbk范围
# 若encode成utf-8 cmd显示亦是乱码,但输出给web页面肯定没问题,因为浏览器支持utf-8啊

具体中文字符的匹配示例

 

Code

 

当然也可以在pattern串中用\u声明具体中文(或其他文)字符,不采用上述的方式(unicode->utf-8)

相关python unicode i/o参见这篇文章http://bakey1985.blogspot.com/2009/01/python-unicode-io.html

3、Python web 开发

用python的web framework进行web开发时,同样需要考虑编码问题,统一编码(python sys、所有文件编码、code文件内的编码声明)避免n多问题

python2.x下对unicode的支持,至少需要你对其有基本的了解方容易解决问题,当然不能跟java、c#相比了,毕竟是从非unicode发展过来的。