1. 基本概念

字符集(Character set)

解释:文字和符合的总称

常见字符集:

Unicode字符集

ASCII字符集(Unicode子集)

GB2312字符集

编码方法(Encoding)

解释:将字符对应到字节的方法,部分字符集和编码方法名称一样。

常见编码方法:

UTF-8:可对Unicode字符进行编码

GB2312

ASCII

编码(Encode)

解释:将字符集中字符按照一定规则转换成字节

解码(Decode)

解释:与编码相反,将字节转换为字符集中的字符

字符集与编码方法的关系

每个字符集都有对应的编码方法

一种字符集可能有多种编码方法

不同的编码方法得到的字节不同,占用存储空间也不一样

例如Unicode字符可以使用UTF-8/ASCII/GBK等方法编码

Unicode字符集包含世界上大部分字符,很多其他字符集有的字符它都有,是他们的超集

大部分字符集可以理解为Unicode的子集

实际上,除了Unicode之外所谓的字符集主要是对Unicode部分字符编码而已(定义编码方式)

一种编码不必支持Unicode的所有字符(通常把它能支持的那部分称为它的字符集)

2. 关于编码的错误和解决方法

在开发过程中,我们所接触的字符集大多都是Unicode,大部分报错都是关于编码和解码的。

2.1. 编码错误UnicodeEncodeError

2.1.1. 错误分析

导致该错误的原因通常是编码方法支持的Unicode字符不全;在工作中,你写了一个txt中文文档,想用ascii编码去保存这个文件,就会报这种错误。

错误复现:

我们知道 ascii 不支持字符 中 ,那我们用 ascii 编码方法对 Unicode 码 中 进行编码:

# -*- encoding: utf-8 -*-

u"中".encode(encoding='ascii')

报错如下:

UnicodeEncodeError: 'ascii' codec can't encode character '\u4e2d' in position 0: ordinal not in range(128)

这是一个 UnicodeEncodeError 类型的错误,提示无法使用指定的编码方法对字符进行编码,报错提示中可以得到3个信息:

当前使用的是acsii编码方法

被编码的字符是'\u4e2d'

ascii编码方法能支持的字符有128个

有时候我们还可以利用这个提示查看编码方法支持的字符个数:

#-*-encoding:utf-8-*-

u"中".encode(encoding='iso-8859-1')

报错:

UnicodeEncodeError: 'latin-1' codec can't encode character '\u4e2d' in position 0: ordinal not in range(256)

通过报错提示可以看出 iso-8859-1 能编256个字符。

接着,我们来看下用支持中文的 utf-8 编码方法进行编码能得到什么结果:

# -*- encoding: utf-8 -*-

s = u"中".encode(encoding='utf-8')

print("s: ", s)

print("s == 中?" , s == '中')

print("type of s: ", type(s))

print("str==bytes? ", bytes == type(s))

输出:

('s: ', '\xe4\xb8\xad')

('s == \xe4\xb8\xad?', True)

('type of s: ', )

('str==bytes? ', True)

从输出的结果可以得到:

- 编码得到的对象跟我们直接定义的字符串是一样的,都是str

- `str`就是`bytes`(python中)

2.1.2. 解决方法

UnicodeEncodeError 是说编码方法支持的字符不全,而 UTF-8 编码就能很好地对Unicode编码,所以只要把编码方法指定为 utf-8 就可以了。

在python2中:

如果你调用 encode 方法但没有指定 encoding 参数,那很可能使用了系统默认的参数,就像:

# -*- encoding: utf-8 -*-

import sys

print "default encoding is %s ." % sys.getdefaultencoding()

u'中'.encode()

输出:

default encoding is ascii .

UnicodeEncodeError: 'ascii' codec can't encode character u'\u4e2d' in position 0: ordinal not in range(128)

可以手动指定encoding参数,也可以修改python默认编码方法:

# -*- encoding: utf-8 -*-

import sys

reload(sys)

sys.setdefaultencoding('utf-8')  # 必须在reload之后调用

print u'中'.encode()

在python3中:

在python3中你很难看到UnicodeEncodeError了,因为python3的默认编码就是utf-8,而Unicode字符都可以用utf-8编码方法编码。

2.2. 编码错误UnicodeDecodeError

2.2.1. 错误分析

导致该错误的原因是使用了错误的解码方式把字节数据还原成字符。例如在工作中,有一个utf-8生成中文文档,我们选择用ascii编码解码,就会报这个错。

错误复现:

我们知道python中字符串和字节是一样,我们可以定义一个中文字符串,通过ascii来解码生成Unicode,复现这个错误:

# -*- encoding: utf-8 -*-

print '中'.decode(encoding='ascii')

输出:

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

注意,这是一个 UnicodeDecodeError 错误,区别于编码错误 UnicodeEncodeError ,它提示无法把字节 0xe4 (实际上 中 对应三字节,0xe4是第一个) 解码成Unicode。0xe4转换为10进制是228,已经超过127了,所以ascii无能力了。

2.2.2. 解决方法

我们需要知道生成字节的编码方式才能进行还原,就好像对一个文件进行了加密,必须得知道加密的密码才能把文件还原,而解码方式(或者称为编码)就是那个密码。 所以不管是python2还是python3直接去修改默认编码为UTF-8不一定能解决问题,具体的方法有两种:

通过源码找到解码失败的字节是使用那种编码生成的

对报错的字节数据使用各种常见的编码进行解码,观察哪一种是正确的

以一个例子来说明为什么直接设置默认编码为UTF-8不能有效解决 UnicodeDecodeError 问题

python文件头指定了编码为,在声明字符串时候将会使用指定的编码转换为字节:

# -*- encoding: GBK -*-

s = "张"

print ("s is ", s)

s_unicode = u'张'

print ("encoding with GBK is ", s_unicode.encode("GBK"))

print ("encoding with UTF-8 is ", s_unicode.encode("UTF-8"))

输出:

('s is ', '\xd5\xc5')

('encoding with GBK is ', '\xd5\xc5')

('encoding with UTF-8 is ', '\xe5\xbc\xa0')

在文件头中指定了GBK编码后默认情况下字符 张 就会被编码为 \xd5\xc5 ,这与我们手动用GBK编码得到结果一致,而使用utf-8编码得到的是3个字节的数据 \xe5\xbc\xa0 (使用了更多的存储空间)。

例子开始了,在python2中将一个dict转换成json:

# -*- encoding: GBK -*-

import json

d = {'name': "张", 'sex': u'man'}

print (json.dumps(d))

输出:

UnicodeDecodeError: 'utf8' codec can't decode byte 0xd5 in position 0: invalid continuation byte

错误说无法使用utf-8解码0xd5,0xd5也就是GBK中的张,我们知道这个字节是用GBK生成的,这个时候可以设置json.dumps的encoding参数解决:

# -*- encoding: GBK -*-

import json

d = {'name': "张", 'sex': u'man'}

print (json.dumps(d, encoding='gbk'))

修改一下代码,继续使用我们熟悉的utf-8编码来执行:

# -*- encoding: utf-8 -*-

import json

d = {'name': "张", 'sex': u'man'}

print (json.dumps(d, encoding='utf-8'))

输出:

{"name": "\u5f20", "sex": "man"}

发现name是unicode,使用ensure_ascii=False,不强制转换成ascii:

# -*- encoding: utf-8 -*-

import json

d = {'name': "张", 'sex': u'man'}

print (json.dumps(d, encoding='utf-8', ensure_ascii=False))

输出:

File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/__init__.py", line 251, in dumps

sort_keys=sort_keys, **kw).encode(obj)

File "/usr/local/Cellar/python@2/2.7.15_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/json/encoder.py", line 210, in encode

return ''.join(chunks)

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

纳尼,文件头也是utf-8,也指定了utf-8怎么还是报错?错误提示用ascii去解码0xe5字节,在上面的代码输出中可以知道0xe5是utf-8对字符 张 编码的第一个字节 ,报错的原因是用ascii去解析utf-8生成的字节了。我们并没有设置哪个地方使用ascii解码,应该是系统默认的编码,尝试设置系统默认编码再执行:

# -*- encoding: utf-8 -*-

import sys

reload(sys)

sys.setdefaultencoding('utf-8')

import json

d = {'name': "张", 'sex': u'man'}

print (json.dumps(d, encoding='utf-8', ensure_ascii=False))

输出:

{"name": "张", "sex": "man"}

3. 总结

3.1. python2和python3对字符串的处理区别

Python2

默认编码是ascii

Python3

import sys;sys.setdefaultencoding('utf-8')

3.2. 为什么不全用UTF-8编码?

UTF-8包含的字符更多,占用的内存和磁盘空间也更大,比如对汉字 张 ,utf-8是3个字节,gbk是2个字节。

3.3. 如何快速解决UnicodeEncodeError错误?

python3中基本不会出现,python2中尝试设置默认编码为utf-8。

3.4. 快速解决UnicodeDecodeError?

需要知道出错的字节是使用哪种编码方式生成的,然后尝试把默认编码设置成这种。

本文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。

python编码用什么软件_彻底解决Python编码问题相关推荐

  1. python编码问题无法复现_彻底解决Python编码问题

    1. 基本概念 字符集(Character set) 解释:文字和符合的总称 常见字符集: Unicode字符集 ASCII字符集(Unicode子集) GB2312字符集 编码方法(Encoding ...

  2. python 折线图中文乱码_彻底解决 Python画图中文乱码问题--Pyplotz组件

    1 源起 自从开始学习Python,就非常喜欢用来画图.一直没有需求画要中文显示信息的图,所以没有配置Python中文的环境.由于昨天就需要画几十个形式相同,只是数据不同的图,并且需要显示中文信息.如 ...

  3. python如何读取log文件_怎么解决Python读取log文件时报错

    怎么解决Python读取log文件时报错 发布时间:2020-05-23 14:15:56 来源:亿速云 阅读:157 作者:鸽子 问题描述: 写了一个读取log文件的Python脚本:# -*- c ...

  4. python开发app的软件_如何利用python开发手机app

    python语言虽然很万能,但用它来开发app还是显得有点不对路,因此用python开发的app应当是作为编码练习,加上目前这方面的模块还不是特别成熟,bug比较多. 准备工作 利用python开发a ...

  5. python输出文件有省略号_如何解决Python输出是省略号的问题

    如何解决 Python 输出是省略号的问题 大家在用 Python 工作的时候是否遇到过 Python 输出是省略号的问题, 那么遇到这种情况后 小伙伴是如何解决的呢 ? 是不是也有刚接触 Pytho ...

  6. python环境配置不成功_怎么解决python配置环境变量不成功

    怎么解决python配置环境变量不成功 发布时间:2020-08-25 16:02:46 来源:亿速云 阅读:94 这期内容当中小编将会给大家带来有关怎么解决python配置环境变量不成功,文章内容丰 ...

  7. python人工智能文字识别软件_怎么用Python人工智能识别图片-百度AI文字识别使用方法分享 - Iefans...

    如果你是个Python初学者,那么你可以试着做做看这个教程,毕竟编程技能都是在实战中成长的,这篇教程是教你如何用Python来进行人工智能识别图片,可以帮助你解决日常办公时遇到的图片转换文字的问题. ...

  8. python中文显示不出来_彻底解决Python里matplotlib不显示中文的问题

    在很长一段时间里用Python绘图,matplotlib都不能很好的显示中文,起初是认为我的pycharm里的设置问题,但是发现同样的问题在spyder里也同样的出现了,虽然有的地方可以用英文实在不行 ...

  9. python无限制邮件群发软件_收藏 - 使用Python通过SMTP协议群发/单发邮件方法

    由于可能需要的功能,寻找可以群发邮件的办法,寻找过几个免费和付费平台,但是均不是特别满意.于是老唐同学说可以用Python结合阿里云邮件推送服务.这里把可以实现的Python SMTP脚本整理出来,脚 ...

最新文章

  1. 【Android 插件化】基于插件化引擎的“恶意应用“与“良性应用“区别 | 恶意插件化应用特征
  2. canvas中strokeRect的渲染问题strokeRect把一像素的边框渲染成两像素
  3. android与html注册登录,Android登录注册源码
  4. 实例化Spring Bean:Bean实例化的姿势有多少种?
  5. Hbase JMX 监控 - Region
  6. SSM中PageHelper的使用步骤与com.github.pagehelper.PageHelper3系列与5系列的区别
  7. oracle分布式数据库中间件,分布式数据库中间件设想
  8. 北大青鸟的班主任好当吗_北大青鸟学校怎么样靠谱吗?
  9. java in查询无法查询到数据(mybatis字符#与字符$的区别)
  10. 简单工厂模式-Simple Factory Pattern
  11. “中国十大名校”之争!
  12. 【数字信号调制】基于matlab多进制数字频率调制(4FSK)【含Matlab源码 999期】
  13. matlab画频谱图
  14. 关于meta标签中的http-equiv属性使用介绍
  15. 公用电信网间互联管理规定
  16. MSP430番外——BSL介绍
  17. 解决 Word 中空格下划线居中后下划线不显示的问题
  18. 小米路由器与edge109版本的问题
  19. 计算机只存在于计算机硬盘上,计算机病毒只存在于计算机硬盘上。()
  20. php+flash头像上传组件

热门文章

  1. 厦门理工计算机课设,厦门理工c++课程设计.doc
  2. Android event log 说明
  3. php基础(25)_构造函数(方法)
  4. 人工智能方向专利和论文相关
  5. LBS游戏火拼三要素:位置、情感、3D渲染
  6. MATLAB | 如何使用MATLAB获取顶刊《PNAS》绘图(附带近3年图像)
  7. 73、基于STM32单片机录音机录音笔语音存储回放播放器TF卡TFT屏系统设计
  8. 费杰:产品经理修炼之道
  9. 最新公路测量计算机,公路工程施工测量计算系统
  10. 华为od机试题 找到好朋友 java解法