美文网首页程序猿日记程序员机器学习与数据挖掘
编程笔记 | 字符编码、Python字符串以及常见异常

编程笔记 | 字符编码、Python字符串以及常见异常

作者: 胖三斤66 | 来源:发表于2018-04-12 10:22 被阅读80次

在讲 Python 字符串之前先了解一下常用的字符编码

常用三种字符编码发展

常用的三种字符编码与特点:

  1. ASCII码 :最早
  2. Unicode : 把所有语言都统一到一套编码
  3. UTF-8 : 相对于Unicode节省空间,并兼容ASCII码

发展由来:
最早的编码是「ASCII码」,其编码范围为 0 - 127,即只能存放127个字符,包括了大小写英文字母、数字和一些符号。每个字符占一个字节。

这样,ASCII 码只能处理英文,那么其他语言字符呢?

其他语言字符编码则是在 ASCII 码基础上扩展。例如,要处理一个中文字符一个字符是不够的,且不能与ASCII码冲突,所以中国制定了「GB2312码」,把中文编进去。但又由于全世界有很多语言,如果都各编各的话,在互相交流就容易产生乱码。

此时「Unicode」把所有语言都统一到一套编码。Unicode字符通常占 2 个字节或以上。Unicode至少占用 2 个字节,这又带来了问题:原本ASCII码中占 1 个字节的A到Unicode要占 2 个字节,就浪费了一倍的存储空间。

为了节省空间,人们又发明了可变长「UTF-8」,它对一个不同范围的
Unicode 字符使用不同长度的编码,如英文字母被编码为 1 个字节,汉字通常为 3 个字节。可以看出,UTF-8包含了ASCII码。故此,大量只支持ASCII编码的历史遗留软件可以在UTF-8编码下继续工作。

三种编码的对比

最后,用一幅图来总结这三种编码演变过程


常用三种字符编码演变过程

计算机系统通用的字符编码工作方式

现在计算机系统通用的字符编码工作方式:

在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或者需要传输的时候,一般就转换为UTF-8编码。

举个例子,当你记事本选择UTF-8格式保存时,记事本的内容按照UTF-8编码存放在硬盘中。而当你在编辑记事本内容(即内容被读取到内存中)
时,UTF-8的字符会被转换Unicode字符放在内存中。

Python2.x 字符串

因为 Python 诞生比 Unicode 早,所以一开始 Python 只支持 ASCII字符串,后面才加上Unicode字符串。故此,Python2.x的字符串的编码方式有两种 :

  1. 按ASCII编码,它是字符串默认的编码方式,对应的字符串类型是str
  2. 按Unicode编码,对应的字符串类型是unicode

举个例子

>>>type('hello')
<type 'str'>
>>> type(u'hello')
<type 'unicode'> 

正因为两种编码方式共存并且我们经常会用到中文字符不包含在 ASCII
中,稍有转换不对就会抛出异常。以下两个异常最为多见:

第一种:「SyntaxError」: Non-ASCII character '\xe4' ...

问题描述
举个例子,在一个 .py 文件中

print u'中'

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

问题产生的原因
根据官方文档的解释是, Python2.x 的解释器默认按 ASCII 编码去读取源代码,而u'中'并不是 ASCII 编码的字符串,所以解释器没法正确读取源代码。

总之,「如果解释器读取源代码按照默认编码方式 ASCII 的话,文件存在中文字符就会报错」

解决方法
官方文档给出的解决方案是在 .py 文件的第一行或第二行加上

# -*- coding: utf-8 -*-

用于申明 Python2.x 解释器按 UTF-8 编码读取文件。

PS :
这里需要注意一下,源代码文件按照 UTF-8 格式存储,仅代表在硬盘中字符按 UTF-8 编码存储。并不是指定 Python解释器读取源代码的编码方式。
但如果不按照 UTF-8 格式存储文件,可能下次打开文件,文件中的中文字符会变成乱码。

第二种:「UnicodeEncodeError」: 'ascii' codec can't encode characters ...

问题描述
举个例子,在一个 .py 文件中

# -*- coding: utf-8 -*-
str(u'中')

Traceback (most recent call last):
 File "E:\test.py", line 3, in <module>
   str(u'中文')
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

问题产生的原因
从异常的提示信息,知道了因为 ASCII 编解码器不能编码 Unicode 字符。
上面说到,Python2.x str() 的编码是 ASCII, ASCII 编解码器只通过范围0-127的字符,超过范围的字符就会报错。其中 u'中' 是 Unicode 且占2个字节,已经超过了127的范围。

总之,「如果存放将 Unicode 字符串强行转换为默认的字符串(str类型)的时候,就会报这种异常」

解决方案

# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

str(u'这')

通过 sys 模块修改解释器默认编码格式后,将默认编码格式也改成 UTF-8, 就变成 Unicode 转 UTF-8,此时转换就没问题了。
放在这个例子中,str是默认的字符串类型,编码方式是 ASCII,修改了解释器的默认编码格式,str的编码方式也跟着改变。

Python3.x 字符串

在 Python3 中,默认字符串编码改为了 Unicode,这样使得 Python 更好地支持多语言了。同样, Python3 依旧支持两种字符串,

  1. Unicode 字符串,是默认的编码格式,不需要在前面加u,对应的类型是 str
  2. Byte 字符串,编码格式是 ASCII,需要在字符串面前加b,例如b'abc'

需要注意的是,
默认情况下,Python 源文件是 UTF-8 编码。在此编码下,全世界大多数语言的字符可以同时用在字符串、标识符和注释中 — 尽管 Python 标准库仅使用 ASCII 字符做为标识符,这只是任何可移植代码应该遵守的约定。如果要正确的显示所有的字符,你的编辑器必须能识别出文件是 UTF-8 编码,并且它使用的字体能支持文件中所有的字符。 Python3 源文件的第一行或者第二行依旧需要加上

# -*- coding: utf-8 -*-

通过此声明,源文件中所有的东西都会被当做用 encoding 指代的 UTF-8 编码对待。

相关文章

  • 编程笔记 | 字符编码、Python字符串以及常见异常

    在讲 Python 字符串之前先了解一下常用的字符编码 常用三种字符编码发展 常用的三种字符编码与特点: ASCI...

  • python 高级方法

    Python的字符串类型 字符编码方法 查看Python中的字符串编码名称,查看系统的编码 源文件字符集编码声明:...

  • Python中的字符串编码

    Python中的字符串编码 定义字符串 Python 中存在两种编码方式的字符串:ASCII 和 Unicode。...

  • Python编码问题

    默认编码 字符串 python2 文本字符串默认编码是ASCII,中文默认UTF-8python3 文本字符串默认...

  • json与python

    Python 对象编码成 JSON 字符串 json.dumps 用于将 Python 对象编码成 JSON 字符...

  • python编码

    python编码 python编码简介 字符串在Python内部的表示是unicode编码,因此,在做编码转换时,...

  • 2018-11-08

    今天,我们深入学习了字符串。学习了字符串编码: python中的字符采用的是Unicode编码 a.什么是编码 ...

  • 字符串与编码

    python的字符串 python 3中,字符串是以unicode编码的,支持多语言。 chr()函数,根据字符的...

  • python学习随便

    Python学习__字符串编码 对于单个字符的编码,Python提供了ord()函数获取字符的整数表示,chr()...

  • python3 (1)基础语法

    1、编码 python3 源码文件默认UTF-8编码,字符串Unicode字符串。可以不在py文件制定编码,pyt...

网友评论

    本文标题:编程笔记 | 字符编码、Python字符串以及常见异常

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