Python编解码问题及文本文件处理方法详解


Posted in Python onJune 20, 2021

编解码器

在字符与字节之间的转换过程称为编解码,Python自带了超过100种编解码器,比如:

  • ascii(英文体系)
  • UTF-8(中文体系)
  • utf-8(全球通用)
  • latin1
  • utf-16

编解码器一般有多个别名,比如utf8、utf-8、U8。

这些编解码器可以传给open()、str.encode()、bytes.decode()等函数的encoding参数。

UnicodeEncodeError

多数非UTF编解码器(比如cp437)只能处理Unicode字符的一小部分子集。把字符转换成字节时,如果目标编码中没有定义这个字符,那么就会抛出UnicodeEncodeError异常。

处理方式一:使用utf8编码。

处理方式二:添加errors参数:

# 忽略 如b'So Paulo'
city.encode("cp437", errors="ignore")
# 替换为? 如b'S?o Paulo'
city.encode("cp437", errors="replace")
# 替换为XML实体 如b'São Paulo'
city.encode("cp437", errors="xmlcharrefreplace")

UnicodeDecodeError

把字节转换为字符时,遇到无法转换的字节时会抛出UnicodeDecodeError异常。这是因为不是每个字节都包含有效的ASCII字符,也不是每个字符都是有效的UTF-8。

处理方式也有两种,跟上面一样。

SyntaxError

Python3默认使用UTF-8编码源码。如果加载的.py模块中包含UTF-8之外的数据,而且没有声明编码,就会抛出SyntaxError异常。

处理方式是在文件顶部添加coding注释:

# coding: cp1252

但是这个办法并不好,最好还是找到这些报错字符,把它们转换为UTF-8。

从网上直接复制代码到IDE中执行经常会报这个错。

处理文本文件

Unicode三明治:

Python编解码问题及文本文件处理方法详解

在程序中尽量少接触二进制,把字节解码为字符,只处理字符串对象。比如在Django中,view应该输出Unicode字符串,Django会负责把响应数据编码成字节序列,而且默认使用UTF-8编码。

Python内置的open函数就是采用了这个原则,在读取文件时会做必要的解码,以文本模式写入文件时会做必要的编码。

文件乱码

Windows更容易遇到这个问题,因为Windows并不是统一的UTF-8编码,比如在Windows10中:

>>> open("cafe.txt", "w", encoding="utf8").write("café")
4
>>> open("cafe.txt").read()
'caf茅'

写入文件时指定了utf8,但是读取文件没有指定,Python就会使用系统默认编码:

>>> import locale
# 打开文件用这个
# 如果没有设置PYTHONENCODING环境变量,sys.stdout/stdin/stderr也用这个
>>> locale.getpreferredencoding()
'cp936'

cp936把最后一个字节解码成了茅而不是é。

>>> import sys
# 二进制数据和字符串之间转换用这个
>>> sys.getdefaultencoding()
'utf-8'
>>> import sys
# 文件名(不是文件内容)用这个
>>> sys.getfilesystemencoding()
'utf-8'

GNU/Linux或Mac OS X不会遇到这个问题,因为多年来它们的默认编码都是UTF-8。

解决办法是一定不能依赖系统默认编码,打开文件时始终应该明确传入encoding=参数,因为不同的设备使用的默认编码可能不同,有时隔一天也会发生变化。

小结

本文介绍了Python的编解码器,以及可能出现的UnicodeEncodeError、UnicodeDecodeError、SyntaxError问题,然后给出了Python的open函数处理文本文件的原则,最后对Windows容易出现的文件乱码问题进行了说明。

到此这篇关于Python编解码问题及文本文件处理方法的文章就介绍到这了,更多相关Python编解码及文本处理内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
用Python实现QQ游戏大家来找茬辅助工具
Sep 14 Python
用python与文件进行交互的方法
Mar 01 Python
Python实现的生产者、消费者问题完整实例
May 30 Python
python获取代码运行时间的实例代码
Jun 11 Python
Python 找到列表中满足某些条件的元素方法
Jun 26 Python
python与caffe改变通道顺序的方法
Aug 04 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
Feb 08 Python
Python内存管理实例分析
Jul 10 Python
python通过http下载文件的方法详解
Jul 26 Python
tensorflow自定义激活函数实例
Feb 04 Python
tensorflow实现训练变量checkpoint的保存与读取
Feb 10 Python
推荐技术人员一款Python开源库(造数据神器)
Jul 08 Python
浅谈Python协程asyncio
Jun 20 #Python
Python3接口性能测试实例代码
Jun 20 #Python
使用Djongo模块在Django中使用MongoDB数据库
python自动计算图像数据集的RGB均值
详解如何用Python实现感知器算法
python中24小时制转换为12小时制的方法
Jun 18 #Python
用Python selenium实现淘宝抢单机器人
You might like
PHP中preg_match函数正则匹配的字符串长度问题
2015/05/27 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
用javascript实现自定义标签
2007/05/08 Javascript
js 创建书签小工具之理论
2011/02/25 Javascript
Javascript数组与字典用法分析
2014/12/13 Javascript
javascript使用for循环批量注册的事件不能正确获取索引值的解决方法
2014/12/20 Javascript
详解JavaScript中的事件流和事件处理程序
2016/05/20 Javascript
简单理解vue中track-by属性
2016/10/26 Javascript
JavaScript实现打地鼠小游戏
2020/04/23 Javascript
解决Mac下安装nmp的淘宝镜像失败问题
2018/05/16 Javascript
JavaScript观察者模式原理与用法实例详解
2020/03/10 Javascript
vue打开子组件弹窗都刷新功能的实现
2020/09/21 Javascript
vue 项目@change多个参数传值多个事件的操作
2021/01/29 Vue.js
[48:26]VGJ.S vs infamous Supermajor 败者组 BO3 第二场 6.4
2018/06/05 DOTA
python base64 decode incorrect padding错误解决方法
2015/01/08 Python
Python新手在作用域方面经常容易碰到的问题
2015/04/03 Python
python 动态加载的实现方法
2017/12/22 Python
python 筛选数据集中列中value长度大于20的数据集方法
2018/06/14 Python
Python基于SMTP协议实现发送邮件功能详解
2018/08/14 Python
python随机数分布random测试
2018/08/27 Python
详解Python 爬取13个旅游城市,告诉你五一大家最爱去哪玩?
2019/05/07 Python
pytorch torch.expand和torch.repeat的区别详解
2019/11/05 Python
Django 实现对已存在的model进行更改
2020/03/28 Python
python matlab库简单用法讲解
2020/12/31 Python
全球性的在线商店:Vogca
2019/05/10 全球购物
PatPat阿根廷:妈妈们的购物平台
2019/05/30 全球购物
利达恒信公司.NET笔试题面试题
2016/03/05 面试题
给酒店员工的表扬信
2014/01/11 职场文书
商场中秋节广播稿
2014/01/17 职场文书
电焊工工作岗位职责
2014/02/06 职场文书
社区健康教育实施方案
2014/03/18 职场文书
敬老模范事迹
2014/05/21 职场文书
机关党员三严三实心得体会
2014/10/13 职场文书
导游经典开场白——导游词
2019/04/17 职场文书
MySQL基于索引的压力测试的实现
2021/11/07 MySQL
mysql 联合索引生效的条件及索引失效的条件
2021/11/20 MySQL