编解码器

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

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

编解码器一般有多个别名,比如utf8utf-8U8

这些编解码器可以传给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三明治:

在程序中尽量少接触二进制,把字节解码为字符,只处理字符串对象。比如在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编解码问题与文本文件处理的更多相关文章

  1. Python 编解码

    字符串编码常用类型:utf-8,gb2312,cp936,gbk等. python中,我们使用decode()和encode()来进行解码和编码 在python中,使用unicode类型作为编码的基础 ...

  2. python rsa 加密解密 (编解码,base64编解码)

    最近有需求,需要研究一下RSA加密解密安全:在网上百度了一下例子文章,很少有文章介绍怎么保存.传输.打印加密后的文本信息,都是千篇一律的.直接在一个脚本,加密后的文本信息赋于变量,然后立马调用解密.仔 ...

  3. python base64 编解码,转换成Opencv,PIL.Image图片格式

    二进制打开图片文件,base64编解码,转成Opencv格式: # coding: utf-8 import base64 import numpy as np import cv2 img_file ...

  4. Python 下JSON的两种编解码方式实例解析

    概念   JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式,易于人阅读和编写.在日常的工作中,应用范围极其广泛.这里就介绍python下它的两种编解码方法: ...

  5. 编解码原理,Python默认解码是ascii

    编解码原理,Python默认解码是ascii 首先我们知道,python里的字符默认是ascii码,英文当然没问题啦,碰到中文的时候立马给跪. 不知道你还记不记得,python里打印中文汉字的时候需要 ...

  6. 【听如子说】-python模块系列-AIS编解码Pyais

    Pyais Module Introduce pyais一个简单实用的ais编解码模块 工作中需要和ais打交道,在摸鱼的过程中发现了一个牛逼的模块,对ais编解码感兴趣的可以拿项目学习一下,或者运用 ...

  7. python中的字符串编码问题——4.unicode编解码(以实际工作中遇到的韩文编码为例)

    韩文unicode编解码  问题是这样,工作中遇到有韩文数据出现乱码,说是unicode码. 类似这样: id name 323 52186863 149 63637538 314 65516863 ...

  8. 编解码-protobuf

    Google的Protobuf在业界非常流行,很多商业项目选择Protobuf作为编解码框架,Protobuf的优点. (1)在谷歌内部长期使用,产品成熟度高: (2)跨语言,支持多种语言,包括C++ ...

  9. 【转】Java web 编解码

    几种常见的编码格式 为什么要编码 不知道大家有没有想过一个问题,那就是为什么要编码?我们能不能不编码?要回答这个问题必须要回到计算机是如何表示我们人类能够理解的符号的,这些符号也就是我们人类使用的语言 ...

随机推荐

  1. JPEG头部解析

    6.3 JPEG格式       6.3.1简介  微处理机中的存放顺序有正序(big endian)和逆序(little endian)之分.正序存放就是高字节存放在前低字节在后,而逆序存放就是低字 ...

  2. 如何通过Zoho Books门户管理供应商

    作为一个企业,不管规模大小,都有自己的供应商来为业务提供相关的服务和配件.随着采购的频率和供应商数量的增加,采购的管理和付款的跟踪难度就会增加,进而影响到企业和供应商之间的关系. 为了解决这个问题,Z ...

  3. MSSQL·备份数据库中的单表

    阅文时长 | 0.11分钟 字数统计 | 237.6字符 主要内容 | 1.引言&背景 2.声明与参考资料 『MSSQL·备份数据库中的单表』 编写人 | SCscHero 编写时间 | 20 ...

  4. 在?开源社区版的 AirTag 请收下——GitHub 热点速览 v.21.21

    作者:HelloGitHub-小鱼干 在比特币跌到怀疑人生的时候,看着"出血不止"的荷包,是时候来"薅"一波羊毛了.openhaystack 能让你免去购买 A ...

  5. [bug] Failed building wheel for xxx

    参考 https://blog.csdn.net/pengzhisen123/article/details/79049834 https://www.lfd.uci.edu/~gohlke/pyth ...

  6. [bug] CDH 安装 Error : No matching Packages to list

    信息 分析 我的系统是CentOS 7,而 cm 安装包是配合 redhat 6 的,应该选择 redhat 7 目录下的包 参考 https://community.cloudera.com/t5/ ...

  7. 3.1.5 LTP(Linux Test Project)学习(五)-LTP代码学习

    3.1.5 LTP(Linux Test Project)学习(五)-LTP代码学习 Hello小崔 ​ 华为技术有限公司 Linux内核开发 2 人赞同了该文章 LTP代码学习方法主要介绍两个步骤, ...

  8. Zabbix 常用术语

    Zabbix 常用术语 1.主机(host) 一台你想监控的网络设备,用IP或域名表示 2.主机组(host group) 主机的逻辑组;它包含主机和模板.-个主机组里的主机和模板之间并没有任何直接的 ...

  9. HAProxy与LVS综合----搭建LNMP源码编译结合HAProxy或LVS负载均衡

    实战一:实现LNMP与Keepalived.HAProxy做反向代理 框架图: 实现原理: 1.当A用户访问网站时,此时需要经过防火墙,防火墙将用户访问的IP地址处理后,如果允许访问,则就访问到HAr ...

  10. 3.socket编程示例

    #block_server.py 非阻塞IO示例#有个疑惑:下面的connfd的blockind要设置为True,不然会出错,待解决from socket import *from time impo ...