• Python标准模块--Unicode


    1 模块简介

    Python 3中最大的变化之一就是删除了Unicode类型。在Python 2中,有str类型和unicode类型,例如,

    Python 2.7.6 (default, Oct 26 2016, 20:30:19) 
    [GCC 4.8.4] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = "blah"
    >>> type(x)
    <type 'str'>
    >>> y = u"blah"
    >>> type(y)
    <type 'unicode'>
    

    如果我们在Python 3中输入同样的代码,你将会发现,最终返回的都是一个字符串类型。

    Python 3.4.3 (default, Nov 17 2016, 01:08:31) 
    [GCC 4.8.4] on linux
    Type "help", "copyright", "credits" or "license" for more information.
    >>> x = "blah"
    >>> type(x)
    <class 'str'>
    >>> y = u"blah"
    >>> type(y)
    <class 'str'>
    

    Python 3默认的是UTF-8编码。这意味着你可以在字符串或者变量名中使用Unciode字符集。让我们看看实际中是如何运用的。

    在Python 2输入如下代码,在变量名中使用Unicode编码,不出意料的化,最终会抛出SyntaxError错误。

    >>> 中国 = "china"
      File "<stdin>", line 1
        中国 = "china"
        ^
    SyntaxError: invalid syntax
    

    在Python 3中输入同样的代码,然后将该变量输出到控制台,可以看到,Unicode变量名在Python 3中可以正常工作。

    >>> 中国 = "china"
    >>> 中国
    'china'
    

    在Python 2中,当读取一个不是ASCII编码的文件或者网页时,我经常会遇到莫名其妙的编码问题。你可能会看到你的输出结果类似于如下示例,

    #Python 2
    >>> "abcdef" + chr(255)
    'abcdefxff'
    

    你将会注意到字符串的末尾有一些有意思的字符。那应该是一个不可显示的字符,而不是xff(xff是这个字符的16进制表示)。在Python 3中,你将会得到你期望的输出,

    #Python 3
    >>> "abcdef" + chr(255)
    'abcdefÿ'
    

    过去我在Python 2中常常通过会调用Python内置的unicode函数来试图解决这个问题。它是将一个字符串转换为Unicode格式。下面的代码哪块出错了?

    #Python 2
    >>> unicode('abcdef' + chr(255))
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 6: ordinal not in range(128)
    

    UnicodeDecodeError错误可以说是Python 2中最为头疼的问题。我曾经在一些项目上花费很多的时间来解决这个问题。我期待在Python 3中不要再和这些问题打交道了。我知道Python 包索引(PyPI)中提供了一个叫做Unidecode的库,可以处理大部分的Unicode字符,并将它们转换为ASCII字符。我已经利用这个工具去解决输入的一些特定问题了。

    2 编码/解码

    你很快就可以了解到你既不能对一个unicode字符串进行解码,也不能对一个str类型的字符串进行编码。如果你尝试对一个unicode类型的字符串解码为ascii,例如,将其转换为字节字符串,你将会得到一个UnicodeEncodeError错误。如下所示,

    # Python 2
    # 解码
    >>> u"xa0".decode("ascii")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode character u'xa0' in position 0: ordinal not in range(128)
    # 编码
    >>> "xa0".encode("ascii")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
    

    如果你在Python 3中输入同样的代码,你就会得到一个AttributeError错误,

    # Python 3
    >>> u"xa0".decode("ascii")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'str' object has no attribute 'decode'
    

    原因就是Python 3中的字符串并没有decode属性。但是字节字符串有decode这个属性,让我们用字节字符串作为示例,

    # Python 3
    >>> b"xa0".decode("ascii")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)
    

    但是ASCII编码依然不知道如何处理我们传入的字符。幸运的是,你可以传入额外的参数用于指定解码方法,如下所示,

    # Python 3
    >>> b"xa0".decode("ascii","replace")
    '�'
    >>> b"xa0".decode("ascii","ignore")
    ''
    

    当我们指定解码方法为替换这个字符或者忽略它,我们可以看到解码后的结果。

    让我们来通过一个Python官方文档中提供的实例,来学习如何对一个字符串进行编码。

    # Python 3
    >>> u = chr(40960) + "abcd" + chr(1972)
    >>> u
    'ꀀabcdu07b4'
    >>> u.encode("ascii")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    UnicodeEncodeError: 'ascii' codec can't encode character 'ua000' in position 0: ordinal not in range(128)
    >>> u.encode("ascii","ignore")
    b'abcd'
    >>> u.encode("ascii","replace")
    b'?abcd?'
    

    这个例子中,我们定义一个字符串,并在字符串的开始和末尾分为添加一个非ASCII字符。然后我们使用编码方法,尝试着将这个字符串转换为一个Unicode字符串的字节表示。第一个尝试失败了,然后返回给我们一个错误。下一个尝试使用了 ignore 标志位,将字符串中的非ASCII字符全部删除。最后一个尝试使用了 replace 标志位,将未知的Unicode字符全部替换为问号。

    如果你右很多与编码相关的任务,Python也提供了codecs模块,你可以参考。

    总结

    截至到目前,你已经对如何使用Unicode非常了解了。Unicode使得你的应用可以在代码中或者输出上支持其他语言。你也初步接触了Pythono中对字符串的编码和解码。对于这部分,Python官方文档提供了非常丰富的资料,如果你需要了解更多,情查阅它。

    3 Reference

    Python 201

  • 相关阅读:
    MySQL基本命令总结
    B+树
    5.Flask-Migrate
    Tornado入门五
    Django之数据库表的单表查询
    MySQL表完整性约束
    MysQL表相关操作
    MySQL库相关操作
    MySQL创建用户+授权+备份
    公司 邮件 翻译 培训 6 长难句
  • 原文地址:https://www.cnblogs.com/zhbzz2007/p/6123117.html
Copyright © 2020-2023  润新知