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 相关文章推荐
使用C语言来扩展Python程序和Zope服务器的教程
Apr 14 Python
python实现根据ip地址反向查找主机名称的方法
Apr 29 Python
python判断windows系统是32位还是64位的方法
May 11 Python
Python2.7编程中SQLite3基本操作方法示例
Aug 09 Python
Python绘制3d螺旋曲线图实例代码
Dec 20 Python
python生成ppt的方法
Jun 07 Python
Python基于sklearn库的分类算法简单应用示例
Jul 09 Python
利用Python如何制作好玩的GIF动图详解
Jul 11 Python
python生成lmdb格式的文件实例
Nov 08 Python
python set集合使用方法解析
Nov 05 Python
在PyCharm中实现添加快捷模块
Feb 12 Python
Python 解析简单的XML数据
Jul 24 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
PHP5+UTF8多文件上传类
2008/10/17 PHP
php 实现进制转换(二进制、八进制、十六进制)互相转换实现代码
2010/10/22 PHP
浅析php原型模式
2014/11/25 PHP
PHP实现的简易版图片相似度比较
2015/01/07 PHP
Laravel中使用阿里云OSS Composer包分享
2015/02/10 PHP
详解PHP中websocket的使用方法
2016/09/15 PHP
权威JavaScript 中的内存泄露模式
2007/08/13 Javascript
小型js框架veryide.librar源代码
2009/03/05 Javascript
jquery.cvtooltip.js 基于jquery的气泡提示插件
2010/11/19 Javascript
给jQuery方法添加回调函数一款插件的应用
2013/01/21 Javascript
jquery自定义滚动条插件示例分享
2014/02/21 Javascript
Bootstrap3学习笔记(二)之排版
2016/05/20 Javascript
JavaScript 监控微信浏览器且自带返回按钮时间
2016/11/27 Javascript
vue mint-ui 实现省市区街道4级联动示例(仿淘宝京东收货地址4级联动)
2017/10/16 Javascript
nginx部署访问vue-cli搭建的项目的方法
2018/02/12 Javascript
js提取中文拼音首字母的封装工具类
2018/03/12 Javascript
vue生命周期实例小结
2018/08/15 Javascript
微信小程序实现随机验证码功能
2018/12/20 Javascript
解决Vue @submit 提交后不刷新页面问题
2020/07/18 Javascript
用Python徒手撸一个股票回测框架搭建【推荐】
2019/08/05 Python
Python列表删除元素del、pop()和remove()的区别小结
2019/09/11 Python
用python写测试数据文件过程解析
2019/09/25 Python
Python实现发票自动校核微信机器人的方法
2020/05/22 Python
python中append函数用法讲解
2020/12/11 Python
俄罗斯旅游网站:Tripadvisor俄罗斯
2017/03/21 全球购物
美国在线乐器和设备商店:Musician’s Friend
2018/07/06 全球购物
Top Villas美国:豪华别墅出租和度假屋
2018/07/10 全球购物
大四自我鉴定范文
2013/10/06 职场文书
乐观大学生的自我评价
2014/01/10 职场文书
新品发布会策划方案
2014/06/08 职场文书
党代会心得体会
2014/09/04 职场文书
2014年组织部工作总结
2014/11/14 职场文书
捐助感谢信
2015/01/22 职场文书
公司员工手册范本
2015/05/14 职场文书
学校2015年纠风工作总结
2015/05/15 职场文书
在 Golang 中实现 Cache::remember 方法详解
2021/03/30 Python