美文网首页
关于Python2编码问题的理解

关于Python2编码问题的理解

作者: keliang19 | 来源:发表于2018-11-01 19:46 被阅读0次

使用Python2处理中文的时候可能会遇到过这样的问题

SyntaxError: Non-ASCII character '\xe4' in file play.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

其中我的代码是这样的

sentence = '你好'

错误信息提示这一行代码中含有非ASCII字符,并且对于这些字符No encoding declared.从错误信息可以看出来Python2默认的编码方式是ASCII。要使用中文需要告诉解释器编码方式是UTF-8。方法是在文件的开头加上# -*- coding: utf-8 -*-.
接下来我又加了一行,目的是想输出句子的长度

sentence = '你好'
print(len(sentence))

此时运行脚本输出的结果是6,而不是2。这其实就涉及到另一个问题,Python2中字符串的存储形式。在Python2中,字符串通常用strunicode两种方式来存储,两者都是basestring的子类。在声明时,类似s='abc'得到的就是str类型的字符串,而s=u'abc'得到的就是unicode类型的字符串。在Python2的内置方法和很多库当中,都是针对unicode来进行操作的。所以在我们的例子中,sentence变量作为一个str类型传给len(),返回结果不是预想中的2。

为了调用Python2中的函数来处理字符串,我们需要实现将str类型的字符串转换成unicode,借助的工具是encode/decode函数。在我们的例子中,进行如下操作

sentence = '你好'
sentence = sentence.decode('utf-8')
print(len(sentence))

运行脚本将会输出2.
如果想将unicode类型转回str类型,执行sentence=sentence.encode('utf-8')即可。或者希望编码成其他形式,比如gbkgb2312,只需要修改编码参数就可以了。

如果我们直接在解释器中操作,会得到以下结果

>>> s = '中文'
>>> s
'\xe4\xb8\xad\xe6\x96\x87'
>>> s = s.decode('utf-8')
>>> s
u'\u4e2d\u6587'
>>> print(s)
中文

为什么sdecode成为unicode之后print(s)还会正常输出呢,这是因为在打印到控制台的时候回自动将unicode编码成控制台支持的编码方式。如果我们人为将其编码方式设置为gbk,将会产生下面的效果

>>> s = s.encode('gbk')
>>> s
'\xd6\xd0\xce\xc4'
>>> print(s)
����

控制台输出了乱码,这是因为s被编码为了gbk格式的,而控制台支持的是utf-8编码。

那么我们其实可以发现,decode/encode配合使用可以实现str编码方式的转变。其实还有一种更简单的方法,直接对str进行encode

# -*- coding: utf-8 -*-
s = '中文'
s = s.encode('gbk')

其实这样做运行起来是会报错的

UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128)

原因是这样的,直接调用str类型的encode函数,它会隐式的首先按照当前的默认编码方式来decodeunicode,然后在encode到指定的编码方式。报错的原因是,默认的编码方式是ascii,无法解析中文。这里的编码和文件头部指定的编码是不一样的,为了不报错,还需要加入

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

这样一来代码就可以正常运行了。介绍这一段的目的是,我在网络上看到好多介绍使用sys.setdefaultencoding('utf-8')来解决编码问题的文章,但是都没有讲清楚他的作用,让人把这两行代码的作用和在文件头部指定# -*- coding: utf-8 -*-混淆了。其实在一般情况下还是最好显示的写sentence.decode(...).encode(...)的形式,这样就不涉及sys当前的默认编码了。

本文长期更新,如果我再踩到Python2中编码的坑还会在这里和大家分享 :)

相关文章

  • 关于Python2编码问题的理解

    使用Python2处理中文的时候可能会遇到过这样的问题 其中我的代码是这样的 错误信息提示这一行代码中含有非ASC...

  • python 编码问题总结记录

    Python2的默认编码ASCII,这是python编码问题的根本原因,可以想象,python3的编码问题肯定没有...

  • Python2和Python3的区别

    编码方式 编码 python2的默认编码是ascii,所以会导致经常会遇到编码问题文件中经常会写# coding=...

  • python编码问题

    1. python2中关于utf-8编码问题解决方法: 或者开头加# -*- coding: utf-8 -*-但...

  • Python3 requests 中文乱码 UnicodeEnc

    最近写程序发现关于requests上传中文参数时候编码有问题,而把代码换成Python2确没有问题,十分困扰,具体...

  • 学习资料

    简明python教程Python2字符编码问题小结stackoverflow about python

  • Python2编码问题

    Python2 源码编码 python2源码默认使用ascii进行编码,当源码中出现中文字符等非ascii编码的字...

  • Python2 编码问题

    一些定义 字符(character)字符是文字的最小的组成单位,其为一种抽象定义(不要与 java 或 c 中的 ...

  • python2编码问题

    由于工作的需要,用了很久的python3又转回来用Python2,所以编码问题又摆在了面前。先看一下python2...

  • Python2 编码问题

    python使用unicode作为中间编码 s.decode('gb2312') 表示将s以gb2312的方式解码...

网友评论

      本文标题:关于Python2编码问题的理解

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