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实现识别手写数字 Python图片读入与处理
Mar 23 Python
django manage.py扩展自定义命令方法
May 27 Python
Python 脚本获取ES 存储容量的实例
Dec 27 Python
在Python中使用Neo4j的方法
Mar 14 Python
用Python中的turtle模块画图两只小羊方法
Apr 09 Python
使用Python Pandas处理亿级数据的方法
Jun 24 Python
python小程序实现刷票功能详解
Jul 17 Python
django ManyToManyField多对多关系的实例详解
Aug 09 Python
python numpy 矩阵堆叠实例
Jan 17 Python
浅谈Python描述数据结构之KMP篇
Sep 06 Python
python 实现图片修复(可用于去水印)
Nov 19 Python
python运算符之与用户交互
Apr 13 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 编写的日历
2006/10/09 PHP
php中使用preg_match_all匹配文章中的图片
2013/02/06 PHP
php安装php_rar扩展实现rar文件读取和解压的方法
2016/11/17 PHP
YII2框架中日志的配置与使用方法实例分析
2020/03/18 PHP
基于javascript数组实现图片轮播
2016/05/02 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
JavaScript的React Web库的理念剖析及基础上手指南
2016/05/10 Javascript
Node.js DES加密的简单实现
2016/07/07 Javascript
jquery.guide.js新版上线操作向导镂空提示jQuery插件(推荐)
2017/05/20 jQuery
Bootstrap标签页(Tab)插件切换echarts不显示问题的解决
2018/07/13 Javascript
解决vue v-for 遍历循环时key值报错的问题
2018/09/06 Javascript
使用wxapp-img-loader自定义组件实现微信小程序图片预加载功能
2018/10/18 Javascript
Vue 基于 vuedraggable 实现选中、拖拽、排序效果
2020/05/18 Javascript
python简单猜数游戏实例
2015/07/09 Python
详解Python nose单元测试框架的安装与使用
2017/12/20 Python
将pandas.dataframe的数据写入到文件中的方法
2018/12/07 Python
python根据文章标题内容自动生成摘要的实例
2019/02/21 Python
使用python 写一个静态服务(实战)
2019/06/28 Python
python issubclass 和 isinstance函数
2019/07/25 Python
Django 源码WSGI剖析过程详解
2019/08/05 Python
python实现回旋矩阵方式(旋转矩阵)
2019/12/04 Python
Python 装饰器原理、定义与用法详解
2019/12/07 Python
Tensorflow 卷积的梯度反向传播过程
2020/02/10 Python
Pytorch mask-rcnn 实现细节分享
2020/06/24 Python
Python 如何对文件目录操作
2020/07/10 Python
Charlotte Tilbury澳大利亚官网:英国美妆品牌
2018/10/05 全球购物
StubHub中国:购买和出售全球活动门票
2020/01/01 全球购物
介绍一下Cookie和Session及他们之间的区别
2012/11/20 面试题
C语言50道问题
2014/10/23 面试题
食品安全承诺书
2014/05/22 职场文书
纪检干部对照检查材料
2014/08/22 职场文书
2015年公共机构节能宣传周活动总结
2015/03/26 职场文书
丧事主持词
2015/07/02 职场文书
运动会新闻报道稿
2015/07/22 职场文书
2016同学毕业寄语大全
2015/12/04 职场文书
SpringBoot集成Druid连接池连接MySQL8.0.11
2021/07/02 Java/Android