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操作MySQL简单实现方法
Jan 26 Python
调试Python程序代码的几种方法总结
Apr 28 Python
整理Python中的赋值运算符
May 13 Python
python 多线程实现检测服务器在线情况
Nov 25 Python
实例解析Python中的__new__特殊方法
Jun 02 Python
python+selenium实现登录账户后自动点击的示例
Dec 22 Python
python使用matplotlib库生成随机漫步图
Aug 27 Python
pyqt5实现俄罗斯方块游戏
Jan 11 Python
深入浅析Python中的迭代器
Jun 04 Python
python tkinter窗口最大化的实现
Jul 15 Python
Django框架视图函数设计示例
Jul 29 Python
Python将视频或者动态图gif逐帧保存为图片的方法
Sep 10 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
页面乱码问题的根源及其分析
2013/08/09 PHP
phpmyadmin中禁止外网使用的方法
2014/11/04 PHP
PHP中使用正则表达式提取中文实现笔记
2015/01/20 PHP
PHP模拟post提交数据方法汇总
2016/02/16 PHP
070823更新的一个[消息提示框]组件 兼容ie7
2007/08/29 Javascript
Jquery 选中表格一列并对表格排序实现原理
2012/12/15 Javascript
『JavaScript』限制Input只能输入数字实现思路及代码
2013/04/22 Javascript
jquery中 $.expr使用实例介绍
2014/06/09 Javascript
jQuery+css实现百度百科的页面导航效果
2014/12/16 Javascript
原生javascript实现解析XML文档与字符串
2016/03/01 Javascript
jQuery Validate插件实现表单验证
2016/08/19 Javascript
AngularJS递归指令实现Tree View效果示例
2016/11/07 Javascript
js仿iphone秒表功能 计算平均数
2017/01/11 Javascript
详解vue + vuex + directives实现权限按钮的思路
2017/10/24 Javascript
vue 自定义 select内置组件
2018/04/10 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
详解VUE前端按钮权限控制
2019/04/26 Javascript
Layui数据表格判断编辑输入的值,是否为我需要的类型详解
2019/10/26 Javascript
vue-cli打包后本地运行dist文件中的index.html操作
2020/08/12 Javascript
JS sort排序详细使用方法示例解析
2020/09/27 Javascript
[56:14]Fnatic vs OG 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
python调用java的jar包方法
2018/12/15 Python
python socket 聊天室实例代码详解
2019/11/14 Python
python实现超级马里奥
2020/03/18 Python
Python3.7 读取音频根据文件名生成脚本的代码
2020/04/07 Python
Python转换字典成为对象,可以用"."方式访问对象属性实例
2020/05/11 Python
广州喜创信息技术有限公司JAVA软件工程师笔试题
2012/10/17 面试题
保护环境建议书300字
2014/05/13 职场文书
代收款委托书范本
2014/10/01 职场文书
大学生个人学习总结
2015/02/15 职场文书
2015年暑期社会实践活动总结
2015/03/27 职场文书
导游词之海南-南湾猴岛
2019/10/12 职场文书
手把手教你实现PyTorch的MNIST数据集
2021/06/28 Python
Python数据处理的三个实用技巧分享
2022/04/01 Python
Java中API的使用方法详情
2022/04/06 Java/Android
Docker部署Mysql8的实现步骤
2022/07/07 Servers