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)
'abcdef\xff'

你将会注意到字符串的末尾有一些有意思的字符。那应该是一个不可显示的字符,而不是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
'ꀀabcd\u07b4'
>>> 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

Python标准模块--Unicode的更多相关文章

  1. Python标准模块--threading

    1 模块简介 threading模块在Python1.5.2中首次引入,是低级thread模块的一个增强版.threading模块让线程使用起来更加容易,允许程序同一时间运行多个操作. 不过请注意,P ...

  2. Python标准模块--logging

    1 logging模块简介 logging模块是Python内置的标准模块,主要用于输出运行日志,可以设置输出日志的等级.日志保存路径.日志文件回滚等:相比print,具备如下优点: 可以通过设置不同 ...

  3. Python标准模块--importlib

    作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 Python提供了importlib包作为标准库的一 ...

  4. Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures

    参考博客: https://www.cnblogs.com/xiao987334176/p/9046028.html 线程简述 什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线 ...

  5. python 全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程什么是线程?线程是cpu调度的最小单位进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的 一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的在当 ...

  6. 【转】Python标准模块--importlib

    [转]Python标准模块--importlib 作者:zhbzz2007 出处:http://www.cnblogs.com/zhbzz2007 欢迎转载,也请保留这段声明.谢谢! 1 模块简介 P ...

  7. Python标准模块--logging(转载)

    转载地址:http://www.cnblogs.com/zhbzz2007/p/5943685.html#undefined Python标准模块--logging 1 logging模块简介 log ...

  8. python全栈开发,Day42(Thread类的其他方法,同步锁,死锁与递归锁,信号量,事件,条件,定时器,队列,Python标准模块--concurrent.futures)

    昨日内容回顾 线程 什么是线程? 线程是cpu调度的最小单位 进程是资源分配的最小单位 进程和线程是什么关系? 线程是在进程中的一个执行单位 多进程 本质上开启的这个进程里就有一个线程 多线程 单纯的 ...

  9. python标准模块(二)

    本文会涉及到的模块: json.pickle urllib.Requests xml.etree configparser shutil.zipfile.tarfile 1. json & p ...

随机推荐

  1. session实现购物车

    为实现简单的购物功能(购物车添加.账户查看.购物车商品删除.实时的购物商品数量及价格的计算显示.购物车商品数量可手动输入等),用session实现了一简单的以php语言为基础.连接MySQL数据库的购 ...

  2. Asp.net Core中使用Session

    前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...

  3. SQL数据库之DQL

    初来乍到,我是一个Java行业的小学生,刚学半年. 今天老师讲了数据库的操作语句,在这里与大家分享一下我学到的知识吧,要是有不足的地方麻烦大家指出来,共同进步,共同提高! 1.数据库中的各种符号 %: ...

  4. 红黑树——算法导论(15)

    1. 什么是红黑树 (1) 简介     上一篇我们介绍了基本动态集合操作时间复杂度均为O(h)的二叉搜索树.但遗憾的是,只有当二叉搜索树高度较低时,这些集合操作才会较快:即当树的高度较高(甚至一种极 ...

  5. js获取给定月份的N个月后的日期

    1.在讲js获取给定月份的N个月后的日期之前,小颖先给大家讲下getFullYear().getYear()的区别. ①getYear() var d = new Date() console.log ...

  6. Golang 编写的图片压缩程序,质量、尺寸压缩,批量、单张压缩

    目录: 前序 效果图 简介 全部代码 前序: 接触 golang 不久,一直是边学边做,边总结,深深感到这门语言的魅力,等下要跟大家分享是最近项目 服务端 用到的图片压缩程序,我单独分离了出来,做成了 ...

  7. 趣说游戏AI开发:曼哈顿街角的A*算法

    0x00 前言 请叫我标题党!请叫我标题党!请叫我标题党!因为下面的文字既不发生在美国曼哈顿,也不是一个讲述美国梦的故事.相反,这可能只是一篇没有那么枯燥的关于算法的文章.A星算法,这个在游戏寻路开发 ...

  8. ASP.NET Core 中文文档 第四章 MVC(4.5)测试控制器逻辑

    原文: Testing Controller Logic 作者: Steve Smith 翻译: 姚阿勇(Dr.Yao) 校对: 高嵩(Jack) ASP.NET MVC 应用程序的控制器应当小巧并专 ...

  9. 数塔问题(DP算法)自底向上计算最大值

    Input 输入数据首先包括一个整数C,表示测试实例的个数,每个测试实例的第一行是一个整数N(1 <= N <= 100),表示数塔的高度,接下来用N行数字表示数塔,其中第i行有个i个整数 ...

  10. Lind.DDD.LindAspects方法拦截的介绍

    回到目录 什么是LindAspects 之前写了关于Aspects的文章<Lind.DDD.Aspects通过Plugins实现方法的动态拦截~Lind里的AOP>,今天主要在设计思想上进 ...