zoukankan      html  css  js  c++  java
  • python 之 字符编码 和 中文显示

    关于编码

    (首先了解一下ascii、gb2312、gbk、utf-8、unicode的关系 http://www.cnblogs.com/skynet/archive/2011/05/03/2035105.html#_3.4.UTF-8)
    a.命令行中编码
    >>> import sys 
    >>> sys.getdefaultencoding()
    'ascii'
    >>> a='nihao中国'
    >>> a
    'nihao\xd6\xd0\xb9\xfa' //‘nihao’是按ascii编码,而中文是按utf-8编码,这么显示是正常的,输出字符实际字节内容,供程序员调试
    >>> print a      //print 才是输出给用户看的内容
    nihao中国
    >>> b='\xd6\xd0\xb9\xfa'
    >>> isinstance(b,unicode) //判断是否为unicode编码
    False
    >>> b1=unicode(b,'gb2312') //转为unicode字符
    >>> isinstance(b1,unicode)
    True
    >>> print b1
    中国
    >>> b1
    u'\u4e2d\u56fd'
    >>> b2=b1.encode('utf-8') //转为utf-8编码
    >>> isinstance(b2,unicode)
    False
    >>> print b2
    中国
    >>> b2
    '\xe4\xb8\xad\xe5\x9b\xbd'
     
    >>> b='hi'+u'you'  #和Unicode连接,产生Unicode字串 
    >>> isinstance(b,unicode)
    True
    >>> b
    u'hiyou'
    >>> str(b)  #内置的str()函数把Unicode字串转换成ASCII字串 
    'hiyou'
     
     >>> a=["你好","abnd"] 
    >>> print a
    ['\xc4\xe3\xba\xc3', 'abnd']
    >>> print a[0]
    你好
    b.程序中编码 
    系统编码如[a]中所示

    当python中间处理非ASCII编码时,经常会出现如下错误: UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128)

    0x??是超出128的数字,python在默认的情况下认为语言的编码是ascii编码,所以无法处理其他编码,需要设置python的默认编码为所需要的编码。
    第一种解决方法就是在代码中添加:
    1. import sys
    2. reload(sys)
    3. sys.setdefaultencoding('utf8') #gb2312,gbk
    4. print sys.getdefaultencoding() # 输出当前编码
    (对我的系统和程序没有起作用)
     
    第二种:
    在 python的Lib\site-packages 文件夹下新建一个sitecustomize.py 文件(sitecustomize.py is a special script; Python will try to import it on startup, so any code in it will be run automatically.),输入:
    1. import sys
    2. sys.setdefaultencoding('utf-8')

    这样就能够自动的设置编码了。

    可以通过第一种方法进行测试。

    ps: 为什么要转码?是因为不同的系统、不同的平台使用的编码不一致(最可能导致中文不能正常显示)。那么,如果你在不同的平台进行输入输出操作,首先你要搞清楚 他们的编码,然后进行转码就ok了

    相关的搜集
    1 http://hi.baidu.com/jiangzubin/item/e3e9072660a690d4ee10f1fd
    关于中文字符串和split()方法打印中文
    >>> a="一 二 三"
    >>> a
    '\xd2\xbb \xb6\xfe \xc8\xfd'
    >>> print a
    一 二 三
    >>> a.split()
    ['\xd2\xbb', '\xb6\xfe', '\xc8\xfd']
    >>> a.split()[0]
    '\xd2\xbb'
    >>> print a.split() //print显示编码,这是问题。或许跟输出方式有关,看下面的解决办法(或解释)
    ['\xd2\xbb', '\xb6\xfe', '\xc8\xfd']
    >>> print a.split()[0]

    >>> print "'%s'" % (",".join(b))
    '一,二,三'

    为什么打印单个元素就可以,而列表就不行?
    print一个对象,是输出其“为了给人(最终用户)阅读”而 
    设计的输出形式,那么字符串中的转义字符需要转出来,而且 
    也不要带标识字符串边界的引号。 
    而在命令行下对对象求值,其输出是为了让程序员探求其内在 
    特征,所以输出结果是对对象的描述。
    现在问题来了,一个list对象,本身就是个数据结构,如果要 
    把它显示给最终用户看,而不是用于给程序员调试时,应该如何 
    “润色”输出格式呢?这显然应该交给程序员去根据应用的需要 
    来做“润色”而不是显示一个用来表示list的方括号,里面却是 
    给最终用户看的“润色”过的结果。这种蹩脚输出,对最终用户 
    很不知所云,对程序员调试程序又没啥意义。
    ps:这段还能理解~print结果针对用户或程序员。就是当我们针对用户用print输出对象时,一般程序员需要对其转义,输出用户期望看到的;
    当我们在命令行下输出,默认是给程序员看的,输出其实质内容,未经转义。(准确讲,并没有出错。)
    : 我也补充一下。 
    :  
    : listobject.c 
    : PyTypeObject PyList_Type = { 
    :         PyObject_HEAD_INIT(&PyType_Type) 
    :         0, 
    :         "list", 
    :         sizeof(PyListObject), 
    :         ... 
    :         (reprfunc)list_repr,                    /* tp_repr */ 
    :         0,                                      /* tp_str */ 
    :         ... 
    : }; 
    :  
    : list.__str__没有实现,所以list.__str__ == object.__str__ 
    : 而运行时的object.__str__会去调用list.__repr__(object.c), 而list.__repr__会对自己的元素调用object.__repr__,所以当元素为str类型的话,就是str.__repr__了 
    ps:程序没看懂,解说算看懂了吧。

    2 还是关于此错误
    UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128)
    参考  http://blog.chinaunix.net/uid-10597892-id-2946918.html
    特别有用的理解:
    字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。
    decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。
    encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。

    3 http://www.360doc.com/content/11/0213/01/2563193_92593666.shtml 
    On my win7(Python 2.7.3)
    >>> s=u"中文"  //明显没事找事,unicode编码有必要拉上中文么,中文为uft-8编码,又来个unicode声明,乱了吧
    >>> print s   //看,乱码了吧
    ÖÐÎÄ
    >>> import sys
    >>> sys.getdefaultencoding()
    'utf-8'
    >>> print s.encode('utf-8')   //本来编码就混乱了,这里encode也会晕的吧,乱码
    脰脨脦脛
    >>> s
    u'\xd6\xd0\xce\xc4'             //看,unicode + utf-8
    >>> print '\xd6\xd0\xce\xc4'    //纯utf-8编码
    中文
    >>> s='中文'
    >>> print s
    中文
    >>> s
    '\xd6\xd0\xce\xc4'

    4 其他
    http://blog.iamzsx.me/show.html?id=81001
    http://hi.baidu.com/l4yn3/item/136bd2157b9ed2456926bb83
    http://www.zhidaow.com/?p=310
    http://www.zhidaow.com/?p=267
    http://baike.baidu.com/view/664966.htm
    http://www.oschina.net/code/snippet_70229_2348
  • 相关阅读:
    【topcoder SRM 702 DIV 2 250】TestTaking
    【24.67%】【codeforces 551C】 GukiZ hates Boxes
    【TP SRM 703 div2 500】 GCDGraph
    【TP SRM 703 div2 250】AlternatingString
    【35.02%】【codeforces 734A】Vladik and flights
    Android总结篇系列:Android Service
    java之常用正则表达式
    一种软件定义的固态盘融合存储方法
    MongoDB常用语句
    编程界十大顶级IDE
  • 原文地址:https://www.cnblogs.com/20120810bubu/p/3036132.html
Copyright © 2011-2022 走看看