zoukankan      html  css  js  c++  java
  • Python 2和Python 3的编码问题

    在Python2中,字符串无法完全地支持国际字符集和Unicode编码。为了解决这种限制,Python2对Unicode数据使用了单独的字符串类型。要输入Unicode字符串字面量,要在第一个引号前加上'u'。Python2中普通字符串实际上就是已经编码(非Unicode)的字节字符串。

    在Python3中,不必加入这个前缀字符,否则是语法错误,这是因为所有的字符串默认已经是Unicode编码了。

    #python2代码
    >>> '张三'  #python2 会自动将字符串转换为合适编码的字节字符串
    'xe5xbcxa0xe4xbfx8a' #自动转换为utf-8编码的字节字符串
    
    >>> u'张三' #显式指定字符串类型为unicode类型, 此类型字符串没有编码,保存的是字符在unicode字符集中的代码序号
    u'u5f20u4fca'
    
    >>> '张三'.encode('utf-8')  #python2 已经自动将其转化为utf-8类型编码,因此再次编码(python2会将该字符串当作用ascii或unicode编码过)会出现错误。
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 0: ordinal not in range(128)
    
    >>> '张三'.decode('utf-8')  #python2 可以正常解码,返回的字符串类是无编码的unicode类型
    u'u5f20u4fca'
    
    >>> b'张三'   # ‘张三' 已被python2转换为utf-8编码,因此已为字节字符串
    'xe5xbcxa0xe4xbfx8a'
    
    >>> print '张三'
    张三
    
    >>> print u'张三'
    张三
    
    >>> print b'张三'
    张三
    
    #python3代码
    >>> '张三' #python3的字符串默认为unicode格式(无编码)
    '张三'
    
    >>> u'张三' #由于默认为unicode格式,因此字符串不用像python2一样显式地指出其类型,否则是语法错误。
    File "<stdin>", line 1
    u'张三'
    ^
    SyntaxError: invalid syntax
    
    >>> type('张三') #python3中文本字符串和字节字符串是严格区分的,默认为unicode格式的文本字符串
    <class 'str'>
    
    >>> '张三'.decode('utf-8') #因为默认的文本字符串为unicode格式,因此文本字符串没有decode方法
    Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    AttributeError: 'str' object has no attribute 'decode'
    
    >>> '张三'.encode('utf-8') #将文本字符串编码,转换为已编码的字节字符串类型
    b'xe5xbcxa0xe4xbfx8a'
    
    >>> type('张三'.encode('utf-8'))
    <class 'bytes'>
    
    >>> print ('张三'.encode('utf-8')) #对于已编码的字节字符串,文本字符串的许多特性和方法已经不能使用。
    b'xe5xbcxa0xe4xbfx8a'
    
    >>>print ('张三'.encode('utf-8'))
    b'xe5xbcxa0xe4xbfx8a'
    
    >>> print ('张三'.encode('utf-8').decode('utf-8'))  #必须将字节字符串解码后才能打印出来
    张三
    

    总结:

    Python 2 中的 str 相当于 Python 3 中的 bytes
    Python 2 中的 unicode 相当于 Python 3中的 str

    Python3 一切都很美好

    在Python3当中,文本字符串类型(使用Unicode数据存储)被命名为 str , 字节字符串类型被命名为 bytes 。一般情况下,实例化一个字符串会得到一个 str 对象 :

    这里写图片描述

    所以现在很多人都说,Python3默认是Unicode,也就是这个意思。
    如果你想得到bytes,那就在文本之前加上前缀 b , 或者 encode 一下。

    这里写图片描述

    所以,很显然,str 对象有一个encode方法,bytes 对象有一个decode方法。

    Python2 相当的操蛋,甚至会误导你

    在Python3中的 str 对象在Python2中叫做 unicode ,感觉很通俗对吧?但 bytes 对象在Python2中叫做 str ,对。。就是你平时用的 str , 默认的那个。。。

    如果你想得到一个文本字符串,你需要在字符串之前加上前缀 u 或者 decode 一下。

    搞笑的还不止这么点,Python2中的 str (字节) 对象,竟然有一个 encode 方法!!!而且你别指望它有什么特殊用处,它就是用来报错的,永远都别使用它!!!
    同样的,unicode (文本字符) 对象也有一个用来报错的 decode 方法。
    我们尝试一下:

    这里写图片描述

    不知道大家注意到错误信息没有,我们在进行解码,规则是GBK,但它说 无法用 ascii 进行编码 ,这是为什么?

    这就是Python2自作聪明为了对一个unicode对象执行解码而进行的隐式编码 ,等于以下代码:

    b.encode('ascii').decode('GBK')
    • 1

    这就是为什么很多人说,Python2的编码很操蛋。

     参考:http://blog.csdn.net/yanghuan313/article/details/63262477

    用于个人学习记录

    做一枚奔跑的老少年!
  • 相关阅读:
    BZOJ1912 [Apio2010]patrol 巡逻
    BZOJ2432 [Noi2011]兔农
    BZOJ1010 [HNOI2008]玩具装箱toy
    BZOJ3240 [Noi2013]矩阵游戏
    洛谷【P1303】A*B Problem
    洛谷【2142】高精度减法
    洛谷【P1100】高低位交换
    OIer应该知道的二进制知识
    洛谷【P3908】异或之和
    洛谷【P2431】正妹吃月饼
  • 原文地址:https://www.cnblogs.com/xiaoshayu520ly/p/8602993.html
Copyright © 2011-2022 走看看