有了这篇文章, Python 中的编码不再是噩梦

python第五话:字符编码 目录 ASCII——英文 GBK——中文 Unicode——各国语言都有 UTF-8——节省空间 计算机通用的字符编码工作方式 常用编码介绍一览表 编码与解码 ASCII——英文 ASCII(American Standard Code for Information Interchange,美国信息互换标准代码)是基于拉丁字母的一套电脑编码系统。它主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。统一规定了常用符号用哪些二进制.. 阅读详情

有了这篇文章, Python 中的编码不再是噩梦

 

Python 中编码问题,一直是很多 Python 开发者的噩梦,尽管你是工作多年的 Python 开发者,也肯定会经常遇到令人神烦的编码问题,好不容易花了半天搞明白了。

一段时间后,又全都忘光光了,一脸懵逼的你又开始你找各种博客、帖子,从头搞清楚什么是编码?什么是 unicode?它和 ASCII 有什么区别?为什么 decode encode 老是报错?python2 里和 python3 的字符串类型怎么都不一样,怎么对应起来?如何检测编码格式?

反反复复,这个过程真是太痛苦了。

今天我把大家在 Python 上会遇到的一些编码问题都讲清楚了,以后你可以不用再 Google,收藏这篇文章就行。

1. Python 3 中 str 与 bytes

在 Python3中,字符串有两种类型 ,str 和 bytes。

今天就来说一说这二者的区别:

  • unicode string(str 类型):以 Unicode code points 形式存储,人类认识的形式
  • byte string(bytes 类型):以 byte 形式存储,机器认识的形式

在 Python 3 中你定义的所有字符串,都是 unicode string类型,使用 type 和 isinstance 可以判别

# python3

>>> str_obj = "你好"
>>> 
>>> type(str_obj)
<class 'str'>
>>> 
>>> isinstance("你好", str)
True
>>> 
>>> isinstance("你好", bytes)
False
>>> 
复制代码

而 bytes 是一个二进制序列对象,你只要你在定义字符串时前面加一个 b,就表示你要定义一个 bytes 类型的字符串对象。

# python3
>>> byte_obj = b"Hello World!"
>>> type(byte_obj)
<class 'bytes'>
>>> 
>>> isinstance(byte_obj, str)
False
>>> 
>>> isinstance(byte_obj, bytes)
True
>>> 
复制代码

但是在定义中文字符串时,你就不能直接在前面加 b 了,而应该使用 encode 转一下。

>>> byte_obj=b"你好"
  File "<stdin>", line 1
SyntaxError: bytes can only contain ASCII literal characters.
>>> 
>>> str_obj="你好"
>>> 
>>> str_obj.encode("utf-8")
b'\xe4\xbd\xa0\xe5\xa5\xbd'
>>> 
复制代码

2. Python 2 中 str 与 unicode

而在 Python2 中,字符串的类型又与 Python3 不一样,需要仔细区分。

在 Python2 里,字符串也只有两种类型,unicode 和 str 。

只有 unicode object 和 非unicode object(其实应该叫 str object) 的区别:

  • unicode string(unicode类型):以 Unicode code points 形式存储,人类认识的形式
  • byte string(str 类型):以 byte 形式存储,机器认识的形式

当我们直接使用双引号或单引号包含字符的方式来定义字符串时,就是 str 字符串对象,比如这样

# python2

>>> str_obj="你好"
>>>
>>> type(str_obj)
<type 'str'>
>>>
>>> str_obj
'\xe4\xbd\xa0\xe5\xa5\xbd'
>>>
>>> isinstance(str_obj, bytes)
True
>>> isinstance(str_obj, str)
True
>>> isinstance(str_obj, unicode)
False
>>>
>>> str is bytes
True
复制代码

而当我们在双引号或单引号前面加个 u,就表明我们定义的是 unicode 字符串对象,比如这样

# python2

>>> unicode_obj = u"你好"
>>>
>>> unicode_obj
u'\u4f60\u597d'
>>>
>>> type(unicode_obj)
<type 'unicode'>
>>>
>>> isinstance(unicode_obj, bytes)
False
>>> isinstance(unicode_obj, str)
False
>>>
>>> isinstance(unicode_obj, unicode)
True
复制代码

3. 如何检测对象的编码(免费领取Python自动化学习资料  工具,面试宝典面试技巧,加QQ群,785128166,群内还会大佬技术交流)

所有的字符,在 unicode 字符集中都有对应的编码值(英文叫做:code point)

而把这些编码值按照一定的规则保存成二进制字节码,就是我们说的编码方式,常见的有:UTF-8,GB2312 等。

也就是说,当我们要将内存中的字符串持久化到硬盘中的时候,都要指定编码方法,而反过来,读取的时候,也要指定正确的编码方法(这个过程叫解码),不然会出现乱码。

那问题就来了,当我们知道了其对应的编码方法,我们就可以正常解码,但并不是所有时候我们都能知道应该用什么编码方式去解码?

这时候就要介绍到一个 python 的库 -- chardet ,使用它之前 需要先安装

python3 -m pip install chardet
复制代码

chardet 有一个 detect 方法,可以 预测其其编码格式

>>> import chardet
>>> chardet.detect('微信公众号:Python编程时光'.encode('gbk'))
{'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
复制代码

为什么说是预测呢,通过上面的输出来看,你会看到有一个 confidence 字段,其表示预测的可信度,或者说成功率。

但是使用它时,若你的字符数较少,就有可能 “误诊”),比如只有 中文 两个字,就像下面这样,我们是 使用 gbk 编码的,使用 chardet 却识别成 KOI8-R 编码。

>>> str_obj = "中文"
>>> byte_obj = bytes(a, encoding='gbk')  # 先得到一个 gbk 编码的 bytes
>>>
>>> chardet.detect(byte_obj)
{'encoding': 'KOI8-R', 'confidence': 0.682639754276994, 'language': 'Russian'}
>>> 
>>> str_obj2 = str(byte_obj, encoding='KOI8-R')
>>> str_obj2
'жпнд'
复制代码

所以为了编码诊断的准确,要尽量使用足够多的字符。

chardet 支持多国的语言,从官方文档中可以看到支持如下这些语言(chardet.readthedocs.io/en/latest/s…)

4. 编码与解码的区别

编码和解码,其实就是 str 与 bytes 的相互转化的过程(Python 2 已经远去,这里以及后面都只用 Python 3 举例)

  • 编码:encode 方法,把字符串对象转化为二进制字节序列

  • 解码:decode 方法,把二进制字节序列转化为字符串对象

那么假如我们真知道了其编码格式,如何来转成 unicode 呢?

有两种方法

第一种是,直接使用 decode 方法

>>> byte_obj.decode('gbk')
'中文'
>>> 
复制代码

第二种是,使用 str 类来转

>>> str_obj = str(byte_obj, encoding='gbk')
>>> str_obj
'中文'
>>> 
复制代码

5. 如何设置文件编码

在 Python 2 中,默认使用的是 ASCII 编码来读取的,因此,我们在使用 Python 2 的时候,如果你的 python 文件里有中文,运行是会报错的。

SyntaxError: Non-ASCII character '\xe4' in file demo.py
复制代码

原因就是 ASCII 编码表太小,无法解释中文。

而在 Python 3 中,默认使用的是 uft-8 来读取,所以省了不少的事。

对于这个问题,通常解决方法有两种:

第一种方法

在 python2 中,可以使用在头部指定

可以这样写,虽然很好看

# -*- coding: utf-8 -*- 
复制代码

但这样写太麻烦了,我通常使用下面两种写法

# coding:utf-8
# coding=utf-8 
复制代码

第二种方法

import sys 

reload(sys) 
sys.setdefaultencoding('utf-8') 
复制代码

这里在调用sys.setdefaultencoding(‘utf-8’) 设置默认的解码方式之前,执行了reload(sys),这是必须的,因为python在加载完sys之后,会删除 sys.setdefaultencoding 这个方法,我们需要重新载入sys,才能调用 sys.setdefaultencoding 这个方法。

关于WPF PasswordBox 增加提示文案,请输入密码,亲测最快方案,改最少的代码!!! 关于WPF PasswordBox 增加提示文案,请输入密码,亲测最快方案,不需要像其他方案改任何PasswordBox的样式,直接加个texbox控件显示隐藏即可1.xaml,注意关键代码,样式之类可以不管 2.xaml.cs 阅读详情

相关推荐

STM32 超声波模块输入捕获测距(标准库)

通道2设置为下降沿触发,触发瞬间会将CNT的记录到CCR2中,由于上升沿触发时已经将CNT置零所以此时的CNT的值就是高电平的持续时间。通道1设置为上升沿触发,触发的瞬间会将CNT的值记录到CCR1里面,同时设置通道1触发带有从模式,并把从模式设置为置零CNT。超声波传感器模块上面通常有两个超声波元器件,一个用于发射,一个用于接收。电路板上有四个引脚:VCC、GND、Trig(触发)、Echo(回应)。输入捕获原理可以看看这位大佬,感觉写的很清楚,工作电压与电流:5V,15mA。感测角度:不小于15度。

qq_62425900的博客 2082

Python3 字符编码

编码 字符串是一种数据类型,但是,字符串比较特殊的是还有一个编码问题。 因为计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特(bit)作为一个字节(byte),所以,一个字节能表示的最大的整数就是255(二进制11111111=十进制255),如果要表示更大的整数,就必须用更多的字节。比如两个字节可以表示的最大整数是65535,4个字节可以...

weixin_30621919的博客 258

ECU-TEST笔记&使用技巧01

说明 1)所述均基于如下环境:ECU-TEST 8.0、Win10系统、NI Veristand 2018(HIL测试)。不排除因为版本及软件环境问题,所述方法不奏效或有更好的方法,欢迎交流,一起提高。 2)本博客以问答形式进行,所述问题均来自于实际测试(包括MIL、HIL测试)遇到的问题及需求,目的是提高测试效率和自动化测试序列的可维护性。 3)本博客尽量从测试方法及ECU-TEST原...

Eigrl的博客 1万+

bytes can only contain ASCII literal characters

Python3则把系统默认编码设置为了 UTF-8。

suichuansuichuan的博客 949

【低轨】Starlink星链-Ku波段下行信号信号结构解析

Starlink播发位于10.7~12.7GHz之间的下行信号,该信号的设计意图是用于宽带网络通信,但是,文章通过对该信号信号体制的详细分析,以及解调出所调制的完整码序列,为利用Starlink信号进行定位解算提供了必要条件。(注,码序列对应的是卫星版本0.9,1.0和1.5)

iseeinvisible的博客 6301

riscv32-gcc工具链实战:从下载到编译的完整指南

本文提供了一份详尽的riscv32-gcc工具链实战指南,涵盖从官方渠道下载预编译版本、正确选择riscv32-glibc版本、配置环境变量到实战编译的全过程。通过清晰的步骤和避坑指南,帮助开发者快速搭建稳定的RISC-V交叉编译环境,并成功编译从Hello World到Linux内核的程序。

s3t4u的博客 675

2.2.python第二章:字符编码

字符串编解码转化 文件(utf-8编码)----(读取:转换为unicode)—>记事本(文字等内容在内存中为unicode编码)-----(保存,转换为utf-8)----->文件(utf-8) 服务器(生成内容由Unicode转换utf-8传输)------>输出utf-8网页内容------->浏览器 print(ord('A'))# 65 print(ord('我'))# 25105 print(chr(65))# A print(chr(2.

eleven的博客 329

《网络安全自学教程》- Windows安全机制:安全标识符,身份鉴别和访问控制

这篇文章详细介绍Windows和Linux如何标识用户,如何根据标识验证用户身份,如何根据用户身份做访问控制。

wangyuxiang946的博客 1万+

Python3编码问题

Python3最重要的进步之一就是解决了Python2中字符串与字符编码的问题。 Python2字符串的缺陷如下: 使用 ASCII 码作为默认编码方式,对中文处理很不友好。 把字符串的牵强地分为 unicode 和 str 两种类型,误导开发者 而Python3则把系统默认编码设置为了 UTF-8>>> import sys >>> sys.getdefaultencodin

云淡风轻 7378

tar解压报错 gzip: stdin: unexpected end of file tar: Unexpected EOF in archive

错误现象: [root@centos7-xinsz08 ~]# tar xf prometheus-2.7.2.linux-amd64.tar.gz gzip: stdin: unexpected end of file tar: 归档文件中异常的 EOF tar: 归档文件中异常的 EOF tar: Error is not recoverable: exiting now 错误原因排查 ...

互联网老辛 2万+

AI 测试工程师 — 6 个月学习计划表

AI 转型测试工程师 —— 6 个月学习计划表

weixin_46453070的博客 1068

一日一技:有了这篇文章, Python 中的编码不再是噩梦

文章来源:Python编程时光作者:写代码的明哥Python 中编码问题,一直是很多 Python 开发者的噩梦,尽管你是工作多年的 Python 开发者,也肯定会经常遇到令人神烦的编码...

简说Python的博客 628

华为OD机试 - 直捣黄龙 - 广度优先搜索BFS(Python/JS/C/C++ 新系统 200分)

从样例 1 可知:5 / 2,2 -> 输出 2 9如果按“移动步数”计算应该是 8,但题目输出是 9,说明这里的“路径长度”统计的是 路径上经过的节点数量。最短路径条数:ways[end]路径长度:dist[end] + 1。

学Java,找哪吒 125

python编程二编码在使用_有了这篇文章, Python 中的编码不再是噩梦

Python 中编码问题,一直是很多 Python 开发者的噩梦,尽管你是工作多年的 Python 开发者,也肯定会经常遇到令人神烦的编码问题,好不容易花了半天搞明白了。一段时间后,又全都忘光光了,一脸懵逼的你又开始你找各种博客、帖子,从头搞清楚什么是编码?什么是 unicode?它和 ASCII 有什么区别?为什么 decode encode 老是报错?python2 里和 python3 的字...

weixin_39989862的博客 106

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

delphi 中文转 ascii编码_有了这篇文章, Python 中的编码不再是噩梦

点击上方“Python编程时光”,选择“加为星标”第一时间关注Python技术干货!Python 中编码问题,一直是很多 Python 开发者的噩梦,尽管你是工作多年的 Python 开发者,也肯定会经常遇到令人神烦的编码问题,好不容易花了半天搞明白了。一段时间后,又全都忘光光了,一脸懵逼的你又开始你找各种博客、帖子,从头搞清楚什么是编码?什么是 unicode?它和 ASCII 有什么...

weixin_39566578的博客 170

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

delphi 中文转 ascii编码_一日一技:有了这篇文章, Python 中的编码不再是噩梦

文章来源:Python编程时光作者:写代码的明哥Python 中编码问题,一直是很多 Python 开发者的噩梦,尽管你是工作多年的 Python 开发者,也肯定会经常遇到令人神烦的编码问题,好不容易花了半天搞明白了。一段时间后,又全都忘光光了,一脸懵逼的你又开始你找各种博客、帖子,从头搞清楚什么是编码?什么是 unicode?它和 ASCII 有什么区别?为什么 decode enco...

weixin_39946996的博客 176

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

怎么查看csv文件的编码_处理统一码文件是场噩梦?这些诀窍助你大梦初醒

全文共2717字,预计学习时长5分钟图片来源:unsplash.com/@christinnoelle对于那些经常在日常工作中处理统一码文件(也适用于其他编码)的人来说,这篇文章是必读的。对于自然语言处理的从业者,处理统一码文件是一场噩梦,尤其是使用Windows操作系统。想象一下,当在编码或解码过程中遇到错误时的沮丧,例如:UnicodeEncodeError: 'mbcs' codec can...

weixin_39982017的博客 3345

python如何将utf-8编码文件改为ansi编码文件_处理统一码文件是场噩梦?这些诀窍助你大梦初醒...

全文共2717字,预计学习时长5分钟图片来源:unsplash.com/@christinnoelle对于那些经常在日常工作中处理统一码文件(也适用于其他编码)的人来说,这篇文章是必读的。对于自然语言处理的从业者,处理统一码文件是一场噩梦,尤其是使用Windows操作系统。想象一下,当在编码或解码过程中遇到错误时的沮丧,例如:UnicodeEncodeError: 'mbcs' codec can...

weixin_35819216的博客 2836

一文搞懂Python字符编码问题,值得收藏!

要说在整个编程领域中最难的问题有哪些的话,字符编码的问题,也就是乱码问题,绝对算得上很多程序员写代码时的一个“噩梦”。以至于在IT界有个著名的笑话,“手持一把锟斤拷,口中直呼烫烫烫”,如果你笑了,那么你肯定是做IT的,哈哈哈。而在python这门语言中,因为python2和python3本身编码机制完全不一样,所以这个问题又尤其突出。包括我本人在内,也被这个编码问题困扰了很久,一直没有完全搞明白。...

weixin_40190184的博客 881

python中去引号_python 去引号

数据类型 | Python从入门到精通:入门篇之五第四节:Python语法学习数据类型5.1数据类型是什么数据类型指的就是变量的值的类型,也就是可以为变量赋哪些值。在Python中,数值分为三种:整数、浮点数(小数)、复数。整数1、Python中所有的整数都是int类型。2、整数大小没有限制,可以是一个无限大的整数。3、如果数字的长度过...文章被纵养的懒猫2019-12-10900浏览量Craz...

weixin_39907850的博客 906

python转换字符串编码_python 转字符

字符串的截取和替换常用方法一:字符串的截取python的字符串是有序集合,我们可以通过索引来提取想要获取的字符,可以把python的字符串也做为字符串的列表就更好理解python的字串列表有2种取值顺序:第一种是从左到右索引默认0开始的,最大范围是字符串长度少1s = 'ilovepython's[0]的结...文章技术小胖子2017-11-16805浏览量Python天天美味(13) - str...

weixin_39849930的博客 944

告别编码乱码:Python开发中编码问题的终极解决方案

在任何涉及字符编码的 Python 代码中,始终显式指定编码,绝不依赖默认值。字符编码本质上是一个"映射"问题:如何在字符的抽象表示(Unicode 码点)和计算机的物理存储(字节序列)之间建立准确的转换规则。Python 3 的str与bytes分离模型,使编码问题从"隐式错误"变成了"显式异常",这实际上是一种进步——它强迫开发者正视编码的存在。当你理解了编码的本质,掌握了encode()和decode()这对核心操作,编码问题就不再是玄学,而是一个可以系统排查和解决的工程问题。

lbbxmx111的博客 258

告别导入噩梦:Nuitka ImportNodes如何驯服Python模块依赖

你是否曾被Python导入错误折磨得抓狂?"ImportError: cannot import name"的红色警告是否让你深夜难眠?作为Python编译器的Nuitka,其导入机制的核心就藏在[ImportNodes模块](https://link.gitcode.com/i/01b98d6e631967bff7625f5e96b95a67)中。这篇文章将带你深入了解Nuitka如何通过Imp...

gitblog_00838的博客 989

处理统一码文件是场噩梦?这些诀窍助你大梦初醒

全文共2717字,预计学习时长5分钟图片来源:unsplash.com/@christinnoelle对于那些经常在日常工作中处理统一码文件(也适用于其他编码)的人来说,...

读芯术的博客 690

python负数字符串转成_python 转字符

字符串的截取和替换常用方法一:字符串的截取python的字符串是有序集合,我们可以通过索引来提取想要获取的字符,可以把python的字符串也做为字符串的列表就更好理解python的字串列表有2种取值顺序:第一种是从左到右索引默认0开始的,最大范围是字符串长度少1s = 'ilovepython's[0]的结...文章技术小胖子2017-11-16783浏览量Python天天美味(13) - str...

weixin_39679718的博客 2593

Python文件写入实战:编码、模式与原子性安全指南

文件写入是程序数据持久化的基础操作,其本质涉及操作系统文件描述符管理、字符编码转换、I/O缓冲机制与并发安全模型。理解UTF-8编码原理可避免跨平台乱码;区分'w'(覆盖)、'a'(追加)、'x'(独占创建)等文件模式,实则是为业务意图建模;而with语句和原子写入(atomic write)则保障了资源确定性释放与数据完整性。这些技术细节共同构成Python工程中‘写得稳、写得准、写得久’的底层能力,广泛应用于日志记录、配置生成、数据导出及结构化存储等核心场景。

cigang4063的博客 568
上一篇: Python中的三个”黑魔法“与”骚操作“,你知道嘛?
下一篇: 很多人不知道的Python 炫技操作:条件语句的七种写法
测试小小小
博客等级 码龄6年 265粉丝 364原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值