zoukankan      html  css  js  c++  java
  • 【python编码】 UnicodeDecodeError 分析和解决

    现象

    环境是linux,python2.7,执行以下代码:

    import json
    
    a = '{"task_id": ["8061964"], "ch_reason": "u589eu52a0u534fu8baeu7ba1u7406u6a21u5757uff0cu7528u6765u7ba1u7406u5b58u6b3eu4ea7u54c1u7684u6cd5u5f8bu534fu8bae", "chg_type": ["0"]}'
    aa = json.loads(a)
    b = '变更原因'
    c = b + aa['ch_reason']
    print c

    出现如下异常:


    原因

    unicode指的是万国码,是一种“字码表”。而utf-8是这种字码表储存的编码方法。unicode不一定要由utf-8这种方式编成bytecode储存,也可以使用utf-16,utf-7等其他方式。目前大多都以utf-8的方式来变成bytecode。

    其中,python里的字符串类型分为byte string 和 unicode string两种。

    如果在python文件中指定编码方式为utf-8(#coding=utf-8),那么所有带中文的字符串都会被认为是utf-8编码的byte string(例如:mystr="你好"),但是在函数中所产生的字符串则被认为是unicode string。


    问题就出在这边,unicode string 和 byte string 是不可以混合使用的,一旦混合使用了,就会产生如上的错误。

    解决方案

    方案一:修改全局默认编码

    import sys
    reload(sys)
    sys.setdefaultencoding('utf-8')


    缺点:一旦加载就修改了全局的编码,有风险。优点:简单粗暴。

    方案二:手动将unicode对象的编码改为utf-8

    将unicode对象的编码改为utf-8,即可和python 中的byte string 之间互相操作了。

    def unicode_convert(input):
        if isinstance(input, dict):
            return {unicode_convert(key): unicode_convert(value) for key, value in input.iteritems()}
        elif isinstance(input, list):
            return [unicode_convert(element) for element in input]
        elif isinstance(input, unicode):
            return input.encode('utf-8')
        else:
            return input
    
    def test():
    	unicode_obj = u'我是unicode'
    	str_obj = unicode_convert(unicode_obj)
    	assert isinstance(str_obj, str)


    如果要在json反序列化中使用,还可以使用以下方式: 

    json.loads(unicode_obj, object_hook=unicode_convert)


    优点:按需转换。 

    缺点:可能有遗漏。

    总结

    方案二更加合适。

  • 相关阅读:
    life
    Android通过XML来定义Menu
    Android通过XML来定义Menu
    Android开发之Menu:OptionMenu(选项菜单)、ContextMenu(上下文菜单)、SubMenu(子菜单)
    作为股权类投资人,我们的投资偏好和投资原则
    作为股权类投资人,我们的投资偏好和投资原则
    给TextView添加超链接的四种方式
    详解ExplosionField的使用,实现View的粉碎效果
    MySql中允许远程连接
    我的投资案例(3)-看好互联网和金融两大朝阳行业,参投入股垂直金融招聘平台"职业梦CareerDream.cn"
  • 原文地址:https://www.cnblogs.com/puyangsky/p/14332224.html
Copyright © 2011-2022 走看看