[Python学习]Unicode及编码处理心得

原文:http://blog.donews.com/limodou/archive/2005/02/22/285118.aspx

如何处理unicode及其它的编码,其实这个问题想明白了很简单:

  1. 字符串有很多的编码
  2. 不同的系统和平台有各自的编码
  3. 为了实现系统或平台之间的信息交互可能需要编码转换
  4. 基本上在两个处理环节上进行转换:你的系统从其它系统读 你的系统从其它系统写
  5. 根据需要进行从源头到目标系统的编码转换

那么常见的环节都有哪些呢,我只能从经验上来回答了?如 NewEdit 使用 wxPython 的unicode版本,那么首先要明白,所有wxPython自带的函数和类都是使用unicode的,哪怕是打开文件对话框这样的从外部输入的类也会自动将文件名转为unicode。然后可能的环节有

  • 使用python的自带模块操作文件系统,如:file()和操作目录等
  • 使用socket发送和接收数据

总之是调用非wxPython的东西都可能需要编码转换

再如XML的处理也是经常有人问的。你应该要记住,当一个XML报文从文件被解析成DOM树时,所有的文本信息都被处理为unicode。然后再考虑与外部环境的交互,看一看是否需要进行编码转换。

在明白有可有需要进行编码转换的地方后,再考查到底需不需要进行编码转换。当调用的内容与你的系统编码一致时,并不需要转换。那么对方系统到底要什么样的编码呢,那只能仔细看文档,靠你的经验,靠你多做测试。而且根据python所报出来的错误一般也可以判断出来。那么当发现需要编码转换时,剩下的就是如何正确进行码制转换。

再举例说明,如你的系统为unicode编码。那么数据有两个流向,一种是调用各种内部或外部的方法来得到数据,这就是读操作。如果是调用系统内的函数,如调用wxPython自已的函数,你可以认为它返回的都是unicode,这样你的系统也为unicode,因此不需要转换。但如果调用的函数返回非unicode,一般需要转换。为什么说一般呢?因为如果返回的是英文串的话,不转换也不会出来,但对于包含中文的情况是会出错的。另一种流向是把系统中的数据传入一个方法中进行处理,这就是写的操作。如果调用的是系统内部的方法,如调用wxPython的方法,你可以认为这个方法需要unicode编码,而数据又是系统中的,因此编码都是unicode,不需要转换。但如果你调用的方法要求其它的编码时,一般需要进行编码转换。对于亚洲语言是特别要考虑这个问题。

常见的编码转换分为以下几种情况:

  • unicode->其它编码

     

    例如:a为unicode编码 要转为gb2312。a.encode(‘gb2312′)

  • 其它编码->unicode

     

    例如:a为gb2312编码,要转为unicode. unicode(a, ‘gb2312′)或a.decode(‘gb2312′)

  • 编码1 -> 编码2

     

    可以先转为unicode再转为编码2

    如gb2312转big5
    unicode(a, ‘gb2312′).encode(‘big5′)

  • 判断字符串的编码

     

    isinstance(s, str) 用来判断是否为一般字符串
    isinstance(s, unicode) 用来判断是否为unicode

  • 如果一个字符串已经是unicode了,再执行unicode转换有时会出错(并不都出错)

     

    可以写一个通用的转成unicode函数:
    def u(s, encoding):
        if isinstance(s, unicode):
            return s
        else:
            return unicode(s, encoding)

那么unicode与utf-8,utf-16有什么区别呢。我认为unicode可以称为抽象编码,也就是它只是一种内部表示,一般不能直接保存。保存到磁盘上时,需要把它转换为对应的编码,如utf-8和utf-16

除上以上的编码方法,在读写文件时还可以使用codecs的open方法在读写时进行转换。

另外我以前写过几篇blog有这方面的介绍:

同时在linuxforum.net上的python版有关于unicode的讨论,可以找一下。 网上也有不少的资料可以查阅。

希望本文对你有帮助。

---------------------------------------------------------------------

帮助我解决了django查询中文的问题:

Log.objects.get(Q(title__contains='嘉宝'.decode('gb2312'))|Q(content__contains='嘉宝'.decode('gb2312')))

同时用到了django查询sql语句的or,用到了Q对象,别忘了 from django.db.models import Q.

关于 ‘or’ 的资料来自:http://docs.djangoproject.com/en/1.0/topics/db/queries/#complex-lookups-with-q-objects

posted @ 2010-06-28 14:41  Phenix.  阅读(904)  评论(0编辑  收藏  举报