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实现在Linux系统下更改当前进程运行用户
Feb 04 Python
Numpy array数据的增、删、改、查实例
Jun 04 Python
python中plot实现即时数据动态显示方法
Jun 22 Python
对pandas读取中文unicode的csv和添加行标题的方法详解
Dec 12 Python
使用python进行波形及频谱绘制的方法
Jun 17 Python
pyqt5实现绘制ui,列表窗口,滚动窗口显示图片的方法
Jun 20 Python
Python使用正则表达式分割字符串的实现方法
Jul 16 Python
python修改FTP服务器上的文件名
Sep 11 Python
python 基于PYMYSQL使用MYSQL数据库
Dec 24 Python
Python3 + Appium + 安卓模拟器实现APP自动化测试并生成测试报告
Jan 27 Python
python使用Windows的wmic命令监控文件运行状况,如有异常发送邮件报警
Jan 30 Python
pd.drop_duplicates删除重复行的方法实现
Jun 16 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中使用Oracle数据库(1)
2006/10/09 PHP
ajax+php实现无刷新验证手机号的实例
2017/12/22 PHP
jQuery中将函数赋值给变量的调用方法
2012/03/23 Javascript
基于jquery实现的一个选择中国大学的弹框 (数据、步骤、代码)
2012/07/26 Javascript
js读取配置文件自写
2014/02/11 Javascript
js/jquery获取文本框输入焦点的方法
2014/03/04 Javascript
浅谈Javascript数组索引
2015/07/29 Javascript
jQuery定义插件的方法
2015/12/18 Javascript
Node.js 文件夹目录结构创建实例代码
2016/07/08 Javascript
easyui简介_动力节点Java学院整理
2017/07/14 Javascript
AngularJS service之select下拉菜单效果
2017/07/28 Javascript
微信小程序组件之srcoll-view的详解
2017/10/19 Javascript
JavaScript实现刮刮乐效果
2020/11/01 Javascript
[03:12]2016完美“圣”典风云人物:单车专访
2016/12/02 DOTA
详细介绍Python函数中的默认参数
2015/03/30 Python
Python中的with语句与上下文管理器学习总结
2016/06/28 Python
python实现实时监控文件的方法
2016/08/26 Python
python SMTP实现发送带附件电子邮件
2018/05/22 Python
django query模块
2019/04/20 Python
解决Python内层for循环如何break出外层的循环的问题
2019/06/24 Python
Python可变对象与不可变对象原理解析
2020/02/25 Python
Selenium启动Chrome时配置选项详解
2020/03/18 Python
PyQt使用QPropertyAnimation开发简单动画
2020/04/02 Python
解决Python数据可视化中文部分显示方块问题
2020/05/16 Python
俄罗斯首家面向中国消费者的一站式购物网站:Wruru
2020/05/08 全球购物
软件测试常见笔试题
2012/02/04 面试题
初中体育教学反思
2014/01/14 职场文书
技术合作协议书范本
2014/04/18 职场文书
毕业评语大全
2014/05/04 职场文书
口才训练演讲稿范文
2014/09/16 职场文书
2014年教师学期工作总结
2014/11/08 职场文书
工程安全生产协议书
2014/11/21 职场文书
新教师个人总结
2015/02/06 职场文书
分享一些Java的常用工具
2021/06/11 Java/Android
Mysql如何实现不存在则插入,存在则更新
2022/03/25 MySQL
Java Spring Lifecycle的使用
2022/05/06 Java/Android