终于搞懂了python2和python3的encode(编码)与decode(解码)
终于搞懂了python2的编码
在python2下碰到非常多次的中文乱码,这次来梳理一下编码问题。
在python 2中默认编码是 ASCII,而在python 3中默认编码是 unicode。
unicode是中间编码,任何字符编码之前的转换都必须解码成unicode,再编码成目标字符编码

在python2读取文件时,如果文件编码是utf-8的,那么中文读取出来前面是带u的,即是unicode编码。
python2编码转换
参考文章开头的图,任何编码转换之前都要解码成unicode,再转换到目标编码。
字节串-->decode('原来的字符编码')-->Unicode字符串-->encode('新的字符编码')-->字节串
# -*- coding: utf-8 -*-
utf_8_a = '中文'
gbk_a = utf_8_a.decode('utf-8').encode('gbk')
print(gbk_a.decode('gbk'))
#输出结果: 中文
在python2中,如果碰到decode为原来的字符编码出错,检查一下你真实的文件编码是否与文件头一致。
python3字符编码
python 3的编码默认是unicode,所以字符编码之间的转换不需要decode过程,直接encode即可
注:在python 3,encode编码的同时会把stringl变成bytes类型,decode解码的同时会把bytes类型变成string类型
如何明显的区分unicode及byte,string
print type(xx)
unicode:
>>> unicode('中文','gbk')
u'\u4e2d\u6587'
byte:
b开头的
python2文件头的UTF-8或GBK会影响乱码
以python2举个例子,当文件编码头是GBK时,在py脚本中住csv中直接写入中文或者打印中文都是没有问题的。
可是当把文件的编码头改成UTF-8时,所有涉及中文的地方都要加上u前缀,否则打印会报错,写入到文件中的会是乱码
报错信息:
File "E:\Code\km\km\km\get_all_none_meta.py", line 70, in main
print '获取完所有无meta的md文件共{}个,结果保存在:{}'.format(len(md_filelist),csv_file_fullpath)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u65e0' in position 11: ordinal not in range(128)
UTF-8下乱码修正:
print '获取完所有无meta的md文件共{}个,结果保存在:{}'.format(len(md_filelist),csv_file_fullpath)
#在UTF-8下要给所有可能会出现中文的字符串前都加上u
print u'获取完所有无meta的md文件共{}个,结果保存在:{}'.format(len(md_filelist),csv_file_fullpath)
python2中字符串前加u有什么作用
在 Python2 中,字符串前面加 u 表示这是一个 Unicode 字符串,即该字符串中可以包含任意 Unicode 字符,而不仅仅是 ASCII 字符集中的字符。如果没有使用 u,那么默认字符串是由 ASCII 字符集组成的,无法包含非 ASCII 字符。
例如,使用 u 前缀可以将带有中文字符的字符串表示为 Unicode 字符串:
u_str = u'这是一个 Unicode 字符串'
如果没有使用 u,则需要使用转义序列来表示中文字符:
str = '\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa Unicode \xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2'
需要注意的是,Python3 中所有的字符串都是 Unicode 字符串,因此不需要在字符串前面加 u。
python2简易处理中文
在一些python2的单文件的小工具中比较简单的处理中文,即不用在字符串前加u转成unicode,我的一个经验是:
把文件编码头改为GBK、GB18030,就不用特殊处理中文了,但会碰到中文在pycharame控制中打印出来是乱码,而在vscode中是好的。
# -*- coding: utf-8 -*-
print ('这是一段中文')#=>这是一段中文
更换编码
# -*- coding: GB18030 -*-
print ('这是一段中文')#=>����һ������
直接运行py文件,中文输出是正常的,可以知道是pycharm的控制台编码设置为了UTF-8
调整sys.setdefaultencoding,没用,因为这是python虚拟机的。
在pycharm中修改全局的编码,没用,也可能是我用的社区版有bug
有这几种方法:
- 在打印log的前面加上u
- 在vscode中运行
最后,为了让兼容性更好地运行在python2及python3中,建议统一使用utf-8编码
python2和python3
- 【中文】这两字GBK编码:\xd6\xd0\xce\xc4
在python2下可以直接打印gbk编码,而python3是不行
Python 2.7.18 (v2.7.18:8d21aa21f2, Apr 20 2020, 13:19:08) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print ('\xd6\xd0\xce\xc4')
中文
从上面的输出也验证这者是等价的:\xd6\xd0\xce\xc4 == 中文
python3
python3的输出如下:
Python 3.8.10 (tags/v3.8.10:3d8993a, May 3 2021, 11:48:03) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> print('\xd6\xd0\xce\xc4')
ÖÐÎÄ
>>> str1 = '中文'.encode('utf8')
>>> str1
b'\xe4\xb8\xad\xe6\x96\x87'
>>> print (str1.decode('utf8'))
中文
>>> print (str1.decode('gbk'))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 2: illegal multibyte sequence
#decode类型不匹配,所以出错
python dict打印出来是编码
如果要显示中文,建议用字符串拼接,而不要用dict。
t={1:"中",2:"hi"} #打印结果 {1: '\xe4\xb8\xad', 2: 'hi'}
t2={1:"china",2:"hi"} #打印结果:{1:"china",2:"hi"}
参考资料
Python基础【day03】:字符转编码操作(五) - 活的潇洒80 - 博客园 (cnblogs.com)
Python中的字符串与字符编码 - 帅丶高高 - 博客园 (cnblogs.com)
终于搞懂了python2和python3的encode(编码)与decode(解码)的更多相关文章
- 终于搞懂了vue 的 render 函数(一) -_-|||
终于搞懂了vue 的 render 函数(一) -_-|||:https://blog.csdn.net/sansan_7957/article/details/83014838 render: h ...
- python2和python3中的编码问题
开始拾起python,准备使用python3, 造轮子的过程中遇到了编码的问题,又看了一下python3和python2相比变化的部分. 首先说个概念: unicode:在本文中表示用4byte表示的 ...
- Python2和Python3的字符串编码和类型
一.字符串编码和类型 任何编码格式的字符串,都可以和Unicode互相转换. gbk -> utf8 # 将字符串按指定格式进行解码,返回Unicode字符串unicode_str = gbk_ ...
- [转]我花了一个五一终于搞懂了OpenLDAP
轻型目录访问协议(英文:Lightweight Directory Access Protocol,缩写:LDAP)是一个开放的,中立的,工业标准的应用协议,通过IP协议提供访问控制和维护分布式信息的 ...
- 探索JAVA并发 - 终于搞懂了sleep/wait/notify/notifyAll
> sleep/wait/notify/notifyAll分别有什么作用?它们的区别是什么?wait时为什么要放在循环里而不能直接用if? ## 简介 首先对几个相关的方法做个简单解释,Obje ...
- 终于搞懂了PR曲线
PR(Precision Recall)曲线 问题 最近项目中遇到一个比较有意思的问题, 如下所示为: 图中的PR曲线很奇怪, 左边从1突然变到0. PR源码分析 为了搞清楚这个问题, 对源码进行了分 ...
- hdu1711(终于搞懂了KMP算法了。。)
题意:给你两个长度分别为n(1 <= N <= 1000000)和m(1 <= M <= 10000)的序列a[]和b[],求b[]序列在a[]序列中出现的首位置.如果没有请输 ...
- Lua的闭包详解(终于搞懂了)
词法定界:当一个函数内嵌套另一个函数的时候,内函数可以访问外部函数的局部变量,这种特征叫做词法定界 table.sort(names,functin (n1,n2) return grades[n1] ...
- 终于搞懂了shell bash cmd...
问题一:DOS与windows中cmd区别 在windows系统中,“开始-运行-cmd”可以打开“cmd.exe”,进行命令行操作. 操作系统可以分成核心(kernel)和Shell(外壳)两部分, ...
- IntelliJ IDEA 部署 Web 项目,终于搞懂了!
这篇牛逼: IDEA 中最重要的各种设置项,就是这个 Project Structre 了,关乎你的项目运行,缺胳膊少腿都不行. 最近公司正好也是用之前自己比较熟悉的IDEA而不是Eclipse,为了 ...
随机推荐
- 2022-10-17:特殊的二进制序列是具有以下两个性质的二进制序列: 0 的数量与 1 的数量相等。 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。 给定一个特殊的二进制序列 S,以
2022-10-17:特殊的二进制序列是具有以下两个性质的二进制序列: 0 的数量与 1 的数量相等. 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量. 给定一个特殊的二进制序列 S,以 ...
- 2021-03-20:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数量。
2021-03-20:给定一个二维数组matrix,其中的值不是0就是1,返回全部由1组成的子矩形数量. 福大大 答案2021-03-20: 按行遍历二维数组,构造直方图. 单调栈,大压小.有代码. ...
- 2021-10-23:位1的个数。编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 ‘1‘ 的个数(也被称为汉明重量)。提示:请注意,在某些语言(如 Java)中
2021-10-23:位1的个数.编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为 '1' 的个数(也被称为汉明重量).提示:请注意,在某些语言(如 Java)中 ...
- C语言之环形队列
一.环形队列的优势 环形队列是一种特殊的队列,它可以解决普通队列在使用时空间利用不充分的问题.在环形队列中,当队列满时,队列的尾指针指向队列的起始位置,而不是指向队列的最后一个元素.这样可以在不浪费空 ...
- 【汇编】DOS系统功能调用(INT 21H)
前言 最近又听了听汇编的课程,发现代码里的MOV xxxxx INT 21H,老师都是一句话带过,而不讲讲其中的原因(也可能前面讲了我没有听QAQ). 顺便夸一下老师,老师懒省事录的视频画质已经成功从 ...
- AcWing901. 滑雪(python)
题目详情 知识点 记忆化DP 思路 自己的思路(仅参考):一开始想的是找最大值,然后从最大值开始向下滑,但是我们是要求最长路径,不一定是从最高的点滑下去的,也不一定是滑到最低点,而且会存在最大值不止一 ...
- 简单了解一下国产CPU
这几天在B站.油管上刷了一些国产芯片真实上手视频,顺便自己也梳理一下芯片的一些基本概念,以及在美国科技制裁和围堵的情况下,国产CPU的发展情况.文末有我整理的一张思维导图,hope u find it ...
- WPF中实现含有中心点Slider双向滑动条
想要实现的效果 原生滑动条 需要认识一下滑动条的组成 在原生控件中生成"资源字典"对应的样式 然后在track所在的列进行添砖加瓦 由于track在row="1" ...
- 《最新出炉》系列初窥篇-Python+Playwright自动化测试-3-离线搭建playwright环境
1.简介 有些小伙伴或者童鞋们私信留言说自己是在公司局域网办公,或者公司为了安全对网络管控比较严格(尤其是一些大的国企.央企),总之就是一句话无法连到外网去在线下载,宏哥刚看到留言时觉得这问题还留言问 ...
- Redis系列17:聊聊布隆过滤器(实践篇)
Redis系列1:深刻理解高性能Redis的本质 Redis系列2:数据持久化提高可用性 Redis系列3:高可用之主从架构 Redis系列4:高可用之Sentinel(哨兵模式) Redis系列5: ...