解决Python3中的中文字符编码的问题

一、原理篇:

Unicode是一32位编码格式,不适合用来传输和存储,所以必须转换成utf-8,gbk等等。这篇文章主要介绍了Python3中的解决中文字符编码的问题,需要的朋友可以参考下

python3中str默认为Unicode的编码格式

Unicode是一32位编码格式,不适合用来传输和存储,所以必须转换成utf-8,gbk等等

所以在Python3中必须将str类型转换成bytes类型的

在Python中使用encode的方式可以进行字符的编码

实际用法:

1

2

3

4

5

>>>a = "中国"

>>> a.encode("utf-8")

b'\xe4\xb8\xad\xe5\x9b\xbd'

>>> a.encode("gbk")

b'\xd6\xd0\xb9\xfa'

总结:

  1. Python中str类型转bytes类型,相当与Unicode转gbk,utf-8。。。类型
  2. b'代表字符编码格式为bytes,
  3. utf-8默认24位占3个8位16进制数
  4. gbk中国编码默认占16位2个8位16进制数字

二、实战篇:

对于在Python代码中直接操作中文汉字的情况,可以考虑在代码文件头部加入万能注释,例如:

#coding = <gbk>

来个小小的例子,在vscode或者其他Python开发工具中(系统自带终端亦同,须正确安装Python开发调试环境,不会的请自行搜索或查看本博主其他文章),我们创建一个名字为“each.py”使用each遍历数组中的成员,目的是把中国古代王朝顺序和主要皇帝姓氏捋一捋,就可以在文件头加入上述的万能注释,以保无虞。示例代码如下:

#coding = <gbk>
member = ['夏','商','西周','东周','秦','西楚','西汉','西汉','东汉','三国(曹魏、蜀汉、东吴)','西晋','东晋','五胡十六国','南朝(宋、齐、梁、陈)','北朝(北魏、东魏、北齐、西魏、北周)','隋朝','唐朝','五代十国','宋(北宋、南宋)','辽','西夏','金','元','明','清','中华民国','中华人民共和国']
for each in member:print(each,len(member))
print('\n''\n')emperor = ['刘(汉、蜀汉、前赵、南朝宋、南汉、北汉)52位','刘氏建立的正统政权为9个','李(成汉、唐、西凉、后唐、南唐、西夏)50位','李氏建立的正统政权为6个','朱(后梁、明)26位','赵(宋)18位','萧(梁、西梁)17位','司马(晋)16位','高(北燕、北齐、南平)12位','王(新、前蜀、闽)10位','石(后赵、后晋)9位','陈(陈)8位','杨(隋、五代十国·吴)7位','张(前凉)7位','马(五代楚)6位','曹(三国魏)5位','钱(吴越)5位','孙(三国吴)4位','冯(北燕)2位','孟(后蜀)2位','段(西燕、北凉)2位','赢(秦)2位','柴(后周)2位','孛儿只斤氏(元、北元)19位','慕容氏(前燕、后燕、西燕)16位','耶律氏(辽)15位','爱新觉罗氏(清)12位','元(北魏、东魏、西魏)11位','完颜氏(金)10位','元氏之前身拓跋氏(北魏)8位','苻(前秦)7位','宇文氏(北周)5位','乞伏氏(西秦)4位','沮渠氏(北凉)4位','秃发氏(南凉)3位','赫连氏(大夏)3位','姚(后秦)3位','吕(后凉)3位等']
for each in emperor:print(each,len(emperor))

在命令模式下进入到 each.py文件所在目录(linux 和MacOS下都使用cd命令,我的存在用户目录“ ~/pythonlab/”下,即可用 “cd ~/pythonlab/”即可进入,ls命令看到each.py后,即可执行运行命令,不会的自行搜索,不再赘述)

执行Python运行命令运行each.py:

(本人安装的是Python3.9的版本,故用的是python3命令启动运行)

 python3 each.py

即可看到如下输出结果:

MacBook-Pro:pythonlab tony$ python3 each.py
夏 27
商 27
西周 27
东周 27
秦 27
西楚 27
西汉 27
西汉 27
东汉 27
三国(曹魏、蜀汉、东吴) 27
西晋 27
东晋 27
五胡十六国 27
南朝(宋、齐、梁、陈) 27
北朝(北魏、东魏、北齐、西魏、北周) 27
隋朝 27
唐朝 27
五代十国 27
宋(北宋、南宋) 27
辽 27
西夏 27
金 27
元 27
明 27
清 27
中华民国 27
中华人民共和国 27刘(汉、蜀汉、前赵、南朝宋、南汉、北汉)52位 38
刘氏建立的正统政权为9个 38
李(成汉、唐、西凉、后唐、南唐、西夏)50位 38
李氏建立的正统政权为6个 38
朱(后梁、明)26位 38
赵(宋)18位 38
萧(梁、西梁)17位 38
司马(晋)16位 38
高(北燕、北齐、南平)12位 38
王(新、前蜀、闽)10位 38
石(后赵、后晋)9位 38
陈(陈)8位 38
杨(隋、五代十国·吴)7位 38
张(前凉)7位 38
马(五代楚)6位 38
曹(三国魏)5位 38
钱(吴越)5位 38
孙(三国吴)4位 38
冯(北燕)2位 38
孟(后蜀)2位 38
段(西燕、北凉)2位 38
赢(秦)2位 38
柴(后周)2位 38
孛儿只斤氏(元、北元)19位 38
慕容氏(前燕、后燕、西燕)16位 38
耶律氏(辽)15位 38
爱新觉罗氏(清)12位 38
元(北魏、东魏、西魏)11位 38
完颜氏(金)10位 38
元氏之前身拓跋氏(北魏)8位 38
苻(前秦)7位 38
宇文氏(北周)5位 38
乞伏氏(西秦)4位 38
沮渠氏(北凉)4位 38
秃发氏(南凉)3位 38
赫连氏(大夏)3位 38
姚(后秦)3位 38
吕(后凉)3位等 38

说明一下:关于代码中的朝代和皇帝姓氏等数据来源于网络,不确保正确与否,历史学家和较真的朋友请自动飘过,本小白是历史盲,不喜勿喷,我们的目的是演示Python开发中的编程思维和解决技术问题的纯技术思路,熟知历史和探讨历史的求饶放过。

关于“如何解决Python3中的中文字符编码的问题”,应该还有其他的方法,有好的思路和经验的朋友们欢迎评论贡献,互相学习,感激不尽^_^

扩展阅读:

附上:Python官方关于此问题解决方案

PEP 263-定义Python源代码编码

PEP: 263
标题: 定义Python源代码编码
作者: 马尔在lemburg.com(马克·安德烈·伦伯格),马丁在v.loewis.de(马丁·冯·洛维斯)
状态: 最后
类型: 标准跟踪
创建时间: 2001年6月6日
Python版本: 2.3
历史后:  

内容

  • 抽象
  • 问题
  • 拟议的解决方案
  • 定义编码
  • 例子
  • 概念
  • 实作
  • 相数
  • 范围
  • 参考文献
  • 历史
  • 版权

抽象

该PEP建议引入一种语法,以声明Python源文件的编码。然后,Python解析器将使用编码信息使用给定的编码来解释文件。最值得注意的是,这增强了源代码中Unicode文字的解释,并使得可以在例如Unicode的编辑器中直接使用UTF-8编写Unicode文字。

问题

在Python 2.1中,只能使用基于Latin-1的编码“ unicode-escape”编写Unicode文字。这使得编程环境对在许多亚洲国家/地区以外的非Latin-1语言环境中生活和工作的Python用户而言相当不利。程序员可以使用最喜欢的编码来编写其8位字符串,但是绑定到Unicode文字的“ unicode-escape”编码。

拟议的解决方案

我建议通过在文件顶部使用特殊注释来声明该编码,从而使每个源文件都可以看到和更改Python源代码编码。

为了使Python知道此编码声明,在处理Python源代码数据方面需要进行一些概念上的更改。

定义编码

如果没有其他编码提示,Python将默认使用ASCII作为标准编码。

要定义源代码编码,必须将魔术注释作为源文件的第一行或第二行放置在源文件中,例如:

<span style="color:#444444">#coding = <编码名称>
</span>

或(使用流行的编辑器认可的格式):

<span style="color:#444444">#!/ usr / bin / python
#-*-编码:<编码名称>-*-
</span>

要么:

<span style="color:#444444">#!/ usr / bin / python
#vim:设置fileencoding = <编码名称>:
</span>

更准确地说,第一行或第二行必须匹配以下正则表达式:

<span style="color:#444444">^ [\ t \ f] *#。*?编码[:=] [\ t] *([-_。a-zA-Z0-9] +)
</span>

然后将此表达式的第一组解释为编码名称。如果Python未知编码,则在编译期间会引发错误。包含编码声明的行上不得有任何Python语句。如果第一行匹配,则第二行将被忽略。

为了帮助诸如Windows之类的平台,该平台在Unicode文件的开头添加了Unicode BOM标记,UTF-8签名 \ xef \ xbb \ xbf也将被解释为“ utf-8”编码(即使没有魔术编码注释也是如此)给出)。

如果源文件同时使用UTF-8 BOM标记签名和魔术编码注释,则注释的唯一允许编码为'utf-8'。任何其他编码都会导致错误。

例子

以下是一些示例,用于阐明在Python源文件顶部定义源代码编码的不同样式:

  1. 使用解释器二进制文件并使用Emacs样式文件编码注释:

    <span style="color:#444444">#!/ usr / bin / python
    #-*-编码:latin-1-*-
    导入操作系统
    ...#!/ usr / bin / python
    #-*-编码:iso-8859-15-*-
    导入操作系统
    ...#!/ usr / bin / python
    #-*-编码:ascii-*-
    导入操作系统
    ...
    </span>
  2. 没有解释器行,使用纯文本:

    <span style="color:#444444">#此Python文件使用以下编码:utf-8
    导入操作系统
    ...
    </span>
  3. 文本编辑器可能以不同的方式定义文件的编码,例如:

    <span style="color:#444444">#!/ usr / local / bin / python
    #编码:latin-1
    导入操作系统
    ...
    </span>
  4. 没有编码注释,Python的解析器将采用ASCII文本:

    <span style="color:#444444">#!/ usr / local / bin / python
    导入操作系统
    ...
    </span>
  5. 编码无效的注释:

    1. 缺少“ coding:”前缀:

      <span style="color:#444444">#!/ usr / local / bin / python
      #latin-1
      导入操作系统
      ...
      </span>
    2. 不在第1行或第2行上编码注释

      <span style="color:#444444">#!/ usr / local / bin / python
      #
      #-*-编码:latin-1-*-
      导入操作系统
      ...
      </span>
    3. 不支持的编码:

      <span style="color:#444444">#!/ usr / local / bin / python
      #-*-编码:utf-42-*-
      导入操作系统
      ...
      </span>

概念

PEP基于以下概念,必须实现这些概念才能使用这种魔术注释:

  1. 完整的Python源文件应使用单一编码。不允许嵌入不同编码的数据,并且在编译Python源代码期间会导致解码错误。

    允许以上述方式处理前两行的任何编码都可以用作源代码编码,其中包括ASCII兼容编码以及某些多字节编码,例如Shift_JIS。它不包括对所有字符使用两个或多个字节的编码,例如UTF-16。这样做的原因是使令牌检测器中的编码检测算法保持简单。

  2. 转义序列的处理应该像现在一样继续工作,但是使用所有可能的源代码编码,即标准字符串文字(8位和Unicode)都可以进行转义序列扩展,而原始字符串文字仅扩展很小的子集转义序列。

  3. Python的tokenizer / compiler组合将需要更新以按以下方式工作:

    1. 读取文件
    2. 假设每文件固定编码,将其解码为Unicode
    3. 将其转换为UTF-8字节字符串
    4. 标记化UTF-8内容
    5. 进行编译,根据给定的Unicode数据创建Unicode对象,并根据Unicode文字数据创建字符串对象,方法是先使用给定的文件编码将UTF-8数据重新编码为8位字符串数据

请注意,Python标识符仅限于编码的ASCII子集,因此在步骤4之后无需进一步转换。

实作

为了与现有代码向后兼容,该代码当前在字符串文字中使用非ASCII且未声明编码,因此将分两个阶段介绍该实现:

  1. 通过内部将缺少的编码声明视为“ iso-8859-1”声明,允许字符串文字和注释中使用非ASCII。这将导致任意字节字符串在处理的步骤2和步骤5之间正确地往返,并为包含非ASCII字节的Unicode文字提供与Python 2.2的兼容性。

    如果在输入中发现非ASCII字节,则会对每个不正确编码的输入文件发送一次警告。

  2. 删除警告,并将默认编码更改为“ ascii”。

内置的compile() API将得到增强,以接受Unicode作为输入。如上所述,8位字符串输入必须经过编码检测的标准过程。

如果将带有编码声明的Unicode字符串传递给compile(),则会引发SyntaxError。

SUZUKI Hisao正在制作补丁。有关详细信息,请参见[2]。[1]提供了仅实现阶段1的补丁。

相数

上面的步骤1和2的实现在2.3中完成,除了将默认编码更改为“ ascii”。

在版本2.5中,默认编码设置为“ ascii”。

范围

该PEP旨在提供从当前(或多或少)未定义的源代码编码情况到更健壮和可移植的定义的升级路径。

参考文献

[1] 第1阶段实施:https: //bugs.python.org/issue526840
[2] 第2阶段实施:https: //bugs.python.org/issue534304

历史

  • 1.10及更高版本:请参阅CVS历史记录
  • 1.8:添加了“。” 到编码RE。
  • 1.7:在第1阶段实施中添加了警告。将Latin-1默认编码替换为解释程序的默认编码。添加了对compile()的调整。
  • 1.4-1.6:细微调整
  • 1.3:Martin v。Loewis的注释工作:UTF-8 BOM标记检测,Emacs样式魔术注释,两阶段实施方法

版权

该文档已放置在公共领域。

来源:https : //github.com/python/peps/blob/master/pep-0263.txt

解决Python3中的中文字符编码的问题-亲测有效相关推荐

  1. python3中默认的字符编码和文件编码_python3 unicod,utf-8,gbk的编码和解码中文显示问题...

    目的: 清楚了解为什么在python3不同的编码,解码,windows,linux操作系统下,字符是否能够正确显示. 前提: 了解不同编码用不同的二级制编码和长度来表示字符. 在python3中,各种 ...

  2. 网页编码与数据传递中的中文字符编码

    最近工作中遇到中文编码,中文参数传递,AJAX返回值包含中文乱码的问题,为此奋斗了一宿,有点心得,有点体会,总结如下,希望对迷惑于此中者有解惑之功效! 在网上一阵狠搜,编码函数的确是有,包括Javas ...

  3. Mac 解决打开txt文件中文乱码(楼主亲测有效)

    在mac系统中打开txt文件会出现中文乱码 TextEdit软件 打开TextEdit软件,进入Preferences 进入Open and Save页签 选择Plain Text File Enco ...

  4. 解决Git中fatal: refusing to merge unrelated histories(亲测)

    Git的报错 在使用Git的过程中有时会出现一些问题,那么在解决了每个问题的时候,都需要去总结记录下来,下次不再犯. 一.fatal: refusing to merge unrelated hist ...

  5. [转载]Java web应用中的常见字符编码问题的解决方法

    以下是 Java web应用的常见编码问题 1. html页面的编码 在web应用中,通常浏览器会根据http header: Content-type的值来决定用什么encoding, 比如遇到Co ...

  6. mysql向表中插中文显示,针对mysql数据库无法在表中插入中文字符的解决方案(彻底解决jav...

    针对mysql数据库无法在表中插入中文字符的解决方案(彻底解决jav 针对mysql数据库无法在表中插入中文字符的解决方案(彻底解决:java.sql.SQLException: Incorrect ...

  7. python django mysql写入中文乱码_解决django 向mysql中写入中文字符出错的问题

    之前使用django+mysql建立的一个站点,发现向数据库中写入中文字符时总会报错,尝试了修改settings文件和更改数据表的字符集后仍不起作用.最后发现,在更改mysql的字符集后,需要重建数据 ...

  8. 解决在全文搜索中搜索中文字符

    解决在全文搜索中搜索中文字符出错补丁:点击下载 http://www.artbbs.net/Demo/Dvbbs_Help/Help_Img/SQLx86.rar 解决中文字符出错问题: 方法一: 把 ...

  9. ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器。用springframework自带的便可...

    ssh框架从页面传中文发生乱码时怎么解决,就是添加一个字符编码拦截器.用springframework自带的便可 转载于:https://www.cnblogs.com/oymx/p/3976392. ...

最新文章

  1. 天池NLP大赛来了!
  2. 又一家明星机器人公司倒掉:曾是全球机器人技术50强,主打性价比AI机械臂
  3. Scala中Unit 类型、Null 类型和 Nothing 类型
  4. linux lua socket编程,CentOs 安装lua,luasocket
  5. oracle+资料类型不一致吗,oracle数据库中,字段类型不一致,导致查询慢
  6. 看完这篇还不了解Nginx,那我就哭了!
  7. java+selenium获取整个表格的内容
  8. 返回值带头信息 php_php与Redis实现分布式锁
  9. 加密芯片在水电气表行业内的应用
  10. 生命在此定格 路透记者遇难前拍下的最后画面
  11. gerrit push失败问题解决
  12. 《大学》全文及白话翻译
  13. win10系统怎么设置网卡优先级
  14. Centos7安装SCL源
  15. 电脑可以使用QQ,但是无法上网的解决方案
  16. oracle lob类型和mysql text_OracleLob类型存储浅析
  17. H3C设备网吧万兆光模块解决方案
  18. android远程控制灯光,11款可用手机远程控制的智能灯
  19. 房屋出租系统(第二版)
  20. AutoHotKey写一个改键的小脚本

热门文章

  1. 【附源码】计算机毕业设计JAVA医院门诊管理系统
  2. 如何学好高中数学学习方法,这四步很重要
  3. python实现按键精灵的功能_利用Python实现Windows下的鼠标键盘模拟的实例代码
  4. xhr是什么缩写_微博上xhr和fsr是什么意思 饭圈里指黄新淳毕雯珺
  5. 2020年国内外12款自助式BI工具最全测评
  6. python科学计算库numpy和绘图库PIL的结合,素描图片(原创)
  7. svn本地连接服务器失败,但是浏览器可以
  8. 谈绿之韵传销斗争路!董事长胡国安感慨十年沉浮
  9. 数据库设计-航班管理系统
  10. Python在Linux 目录的常用操作命令