首页 > 编程语言 > 终于搞懂了python2和python3的encode(编码)与decode(解码)

终于搞懂了python2和python3的encode(编码)与decode(解码)

时间:2023-08-10 23:22:48浏览次数:45  
标签:编码 中文 print decode 字符串 encode 搞懂 python2

终于搞懂了python2的编码

在python2下碰到非常多次的中文乱码,这次来梳理一下编码问题。

在python 2中默认编码是 ASCII,而在python 3中默认编码是 unicode。

unicode是中间编码,任何字符编码之前的转换都必须解码成unicode,再编码成目标字符编码

image-20230808144605168

在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

有这几种方法:

  1. 在打印log的前面加上u
  2. 在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)

标签:编码,中文,print,decode,字符串,encode,搞懂,python2
From: https://www.cnblogs.com/zhaoqingqing/p/17621867.html

相关文章

  • XMLEncoder生成的xml文档的schema分析
    以下文为基础,进行分析LongTermPersistenceofJavaBeansComponents:XMLSchemahttp://java.sun.com/products/jfc/tsc/articles/persistence3/ 1BasicElements每个xml以一个可选的<?xmlversion="1.0"encoding="UTF-8"?>开头,接着是<javaversion="1.4.0&q......
  • pg库报UnicodeDecodeError 'ascii' codec can't decode byte 0xe4 in position 0 ordi
    UnicodeDecodeError'ascii'codeccan'tdecodebyte0xe4inposition0ordinalnotinrange128其实就是加个:client_encoding配置#1、直接使用psycopg2def__init__(self,dict_flag=False):self.conn=psycopg2.connect(host=PostgresParams().get_host()......
  • 基于Pair-wise和CrossEncoder训练单塔模型
    本文分享自华为云社区《语义检索系统排序模块:基于ERNIE-Gram的Pair-wise和基于RocketQA的CrossEncoder训练单塔模型》,作者:汀丶。文本匹配任务数据每一个样本通常由两个文本组成(query,title)。类别形式为0或1,0表示query与title不匹配;1表示匹配。基于单塔Point-wise范......
  • 基于RocketQA的CrossEncoder训练单塔模型
    本文分享自华为云社区《语义检索系统排序模块:基于ERNIE-Gram的Pair-wise和基于RocketQA的CrossEncoder训练单塔模型》,作者:汀丶。 文本匹配任务数据每一个样本通常由两个文本组成(query,title)。类别形式为0或1,0表示query与title不匹配;1表示匹配。基于单塔Point-wise范式......
  • 软件测试|json.decoder.JSONDecodeError: Expecting ‘,‘错误解决
    在处理JSON数据时,有时可能会遇到"json.decoder.JSONDecodeError:Expecting','"的错误,如下图的情况,本文将介绍这个错误的原因以及一些常见的解决方法。错误原因"json.decoder.JSONDecodeError:Expecting','"错误通常发生在解析JSON数据时,Python解析器期望在JSON对象或数组的元素......
  • 专业视频和音频编码应用Media Encoder 2023(ME2023)mac中文版
    MediaEncoder是一个可定制的专业编辑器。在开发过程中,您可以不断调整和更新工具。它具有独特的动态编辑体验,您可以将其设置为默认值。这是一个完全免费的多语言工具,支持扩展。为您提供一个多平台编辑器平台,可以使用所有现有的,新的和改进的。→→↓↓载MediaEncoder2023Mac......
  • c volatile一文搞懂
    关键字volatile简单来说就两个作用:保证不被编译器优化例如重复的赋值volatileintvalue=10;value=10;value=10;volatile修饰后,一是这几个语句都会得到执行,二是顺序不会改变保证可见性这里可见性的意思是,在多线程的环境下,当一个线程对一个变量改变,另一个线程......
  • 第四天——搞懂问题
    问题1:#include<stdio.h>和#include"stdio.h"有什么区别?1、#include<>一般用于包含系统头文件,诸如stdlib.h、stdio.h、iostream等;2、#include""一般用于包含自定义头文件,比如我们自定义的test.h、declare.h等。'这是因为:查找范围不同:""会优先查找自己项目工程下文件,查......
  • PostMan 如何在x-www-form-urlencode调试List<string>
    分析:第三方支持两种post请求方式: application/json和application/x-www-form-urlencode方式一:正常方式二异常:参数[loginIds]当前类型[String]转成目标类型[List]异常使用数组方式:数据统计不一致,不报错解决方案:命名至少两个相同的变量名称,变量名为空的也不能省略c#实现部分代码: /......
  • 语义检索系统之排序模块:基于ERNIE-Gram的Pair-wise和基于RocketQA的CrossEncoder训练
    语义检索系统之排序模块:基于ERNIE-Gram的Pair-wise和基于RocketQA的CrossEncoder训练的单塔模型文本匹配任务数据每一个样本通常由两个文本组成(query,title)。类别形式为0或1,0表示query与title不匹配;1表示匹配。基于单塔Point-wise范式的语义匹配模型ernie_matchi......