Python中编码问题总结

作者: AllinGo | 来源:发表于2017-08-05 23:27 被阅读21次

    Python中的字符串编码是一个很让初学者费解头疼的问题,特别是遇到中文时相关处理经常抛出Exception。字符串到底以什么编码在Python内部进行处理,Python2.x中文编码如何安全的转换,Python 2.x与Python 3.x在编码方面的区别?本文接下来会一一进行讲解。

    1、字符串在Python内部的编码
    在Python内部字符串都是以unicode编码进行处理,即源码文件中的字符串首先都会被decode成unicode编码的字符串,之后Python内部再进行处理,用代码显示表示如下:

    unicode_str = input_str.decode('utf8')
    

    以上是将uft8编码的字符串input_str转换为unicode,decode成功的前提是你得知道input_str的原始编码,比如这里是utf8,否则会抛出UnicodeDecodeError的异常。

    2、Python源码字符串的编码
    Python 2.x的默认编码格式是ascii,字符串在转换前均会decode成unicode。初学Python大家可能会编写如下的代码:

    #!/usr/bin/python
    s = '你好'
    print s
    

    会出现下面的异常:

    SyntaxError: Non-ASCII character '\xe4'
    

    这个是因为错误的将utf8编码的中文当成ascii解码。解决方法也很常规:在Python源码文件中声明编码格式,最常见的声明方式如下:

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

    3、字符串编码安全的转换方式
    我们常见的字符串处理场景是这样的,从文件中或者中MySQL/Redis中load一段数据,做一些split、find之类的操作,这不是在代码文件中已有的变量,动态加载的字符串并不会自动decode成unicode编码。因此遇到中文时需要我们显示的使用decode函数处理。若已知load字符串的编码格式,直接转换即可。大部分情况下并不知道load字符串的编码,这里可以借住chardet插件检测字符串的原始编码:

    // 安装chardet库
    pip install chardet
    result = chardet.detect(s)
    // 检测结果
    >>> result
    {'confidence': 0.99, 'encoding': 'utf-8'}
    

    confidence表示检测的准确率,encoding表示检测的编码,关于chardet的原理这里不说了。数据处理完了,如果需要再次存储,使用encode方法即可

    // 将unicode编码转为目标编码:utf8
    out_put = str.encode('utf8')
    

    4、Python 2.x与Python 3.x区别
    使用Python 3.x版本可以解决大部分编码问题,Python 3.x把系统默认编码设置为utf8,被单引号或双引号括起来的字符串,就已经是 Unicode 类型的str。文本字符和二进制数据区分得更清晰,分别用 str 和 bytes 表示。文本字符全部用 str 类型表示,str 能表示 Unicode 字符集中所有字符,而二进制字节数据用一种全新的数据类型,用 bytes 来表示。

    终极原则:decode early, unicode everywhere, encode late
    在输入或者声明字符串的时候,尽早地使用decode方法将字符串转化成unicode编码格式;然后在程序内使用字符串的时候统一使用unicode格式进行处理;最后,在输出字符串的时候,通过encode方法将字符串转化为你所想要的编码格式。

    参考:

    相关文章

      网友评论

        本文标题:Python中编码问题总结

        本文链接:https://www.haomeiwen.com/subject/lzawlxtx.html