热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

彻底搞懂Python编码

 因为中文的特殊编码,导致Python2和Python3使用过程中的各种编码问题,如果不清楚其中的关联关系,那么这就一直是个大坑,不是懵逼就还是懵逼,所以就目前碰到的情况彻底梳理下

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

 

因为中文的特殊编码,导致 Python2 和 Python3 使用过程中的各种编码问题,如果不清楚其中的关联关系,那么这就一直是个大坑,不是懵逼就还是懵逼,所以就目前碰到的情况彻底梳理下 Python2 和 Python3 中编码的关系和区别,以作备忘。

先说下涉及编码格式的几个地方:


  1. 脚本字符编码:就是经常在脚本文件开头看到的 # -*- coding: utf-8 -*-,如果使用 Python2,没有显式声明的话默认使用 ASCII 格式,Python3 默认使用 utf-8 格式;



  2. 解释器字符编码:可以通过函数 sys.getdefaultencoding() 查看,Python2 默认是 ASCII,Python3 默认使用 utf-8;



  3. 脚本文件存储编码:就是 py 脚本文件本身在物理介质上面的存储格式,通常有 ASCII、GBK、utf-8 等格式。



下面我们把上述编码分别在脚本中进行组合使用后,再使用 Python2.6 和 Python3.4 运行,看看实际都什么效果。


1.默认脚本文件编码 + 文件存储使用 gbk

脚本内容:

import sys
print(sys.getdefaultencoding())
print('中文')

使用 Python2.6 运行的结果如下,提示gbk 编码字符 \xd6 非 ASCII 字符:

> python26 test_gbk.py
 File "test_gbk.py", line 4SyntaxError: Non-ASCII character '\xd6' in file test_gbk.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

使用 Python3.4 运行的结果如下,提示gbk 编码字符 \xd6 非 utf-8 字符:

> python26 test_gbk.py
 File "test_gbk.py", line 4SyntaxError: Non-UTF-8 code starting with '\xd6' in file test_gbk.py on line 4, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

结论:默认的 gbk 编码中文,Python2的解释器字符编码(ASCII)和 Python3的解释器字符编码(utf-8)格式都没法识别,因为 ASCII 编码不包含中文,而 utf-8 是 3 字节编码,gbk 是 2 字节编码,所以都识别不了了。


2.脚本文件编码 gbk + 文件存储使用 gbk

在刚才的脚本头部显式声明脚本文件编码格式为 gbk:

#coding:gbkimport sys
print(sys.getdefaultencoding())
print('中文')

使用 Python2.6 运行的结果:

> python26 test_gbk.py
ascii
中文

使用 Python3.4 运行的结果:

> python34 test_gbk.py
utf-8中文

结论:文件使用的 gbk 格式存储,同时显式声明了脚本文件编码为 gbk,Python2 和 Python3 都可以正常处理。


3.脚本文件编码 utf-8 + 文件存储使用 gbk

在刚才的脚本头部显式声明脚本文件编码格式为 utf-8:

# -*- coding: utf-8 -*-import sys
print(sys.getdefaultencoding())
print('中文')

使用 Python2.6 运行的结果正常:

> python26 test_gbk.py
ascii
中文

使用 Python3.4 运行的结果如下,提示尝试使用 utf-8 解码字符 0xd6 时异常:

> python34 test_gbk.py
File "test_gbk.py", line 6SyntaxError: (unicode error) 'utf-8' codec can't decode byte 0xd6 in position 0: invalid continuation byte

结论:文件使用的 gbk 格式存储,同时显式声明了脚本文件编码为 utf-8时,但是 Python2 在 Windows 平台还是使用 gbk 进行输出,所以解析正常,而 Python3 使用 utf-8 所以解析异常。


4.默认脚本文件编码 + 文件存储使用 utf-8

去掉之前脚本头部的声明,然后使用 utf-8 格式存储文件(注意,不能在刚才的文件基础上强制修改存储编码,强制转换会出现中文乱码的问题,建议先新建一个 utf-8 格式的文件,然后再输入中文):

import sys
print(sys.getdefaultencoding())
print('中文')

使用 Python2.6 运行的结果如下,ASCII 也识别不了 utf-8 格式的字符 \xe4:

> python26 test.py
 File "test.py", line 4SyntaxError: Non-ASCII character '\xe4' in file test.py on line 4, but no encoding declared; see http://www.python.org/peps/pep-0263.html for details

使用 Python3.4 运行的结果,可以正常识别,因为 Python3 默认使用 utf-8 编码:

> python34 test.py
utf-8中文

结论:默认的 utf-8 编码中文,Python2 会默认使用 ASCII 读取,所以没法识别,Python3 可以正常识别。


5.脚本文件编码 gbk + 文件存储使用 utf-8

脚本头部显式声明脚本文件编码格式为 gbk,同时使用 utf-8 格式存储文件:

#coding:gbkimport sys
print(sys.getdefaultencoding())
print('中文')

使用 Python2.6 运行的结果如下,使用 gbk 根本读取不了 utf-8 格式任何内容:

> python26 test.py
File "test.py", line 6SyntaxError: 'gbk' codec can't decode bytes in position 9-10: illegal multibyte sequence

使用 Python3.4 运行的结果如下,其实和上面错误一样,但是提示更直接了:

> python34 test.py
File "test.py", line 1SyntaxError: encoding problem: gbk

结论:默认的 utf-8 编码中文,如果显式指定使用 gbk 读取,Python2 和 Python3 都没法做到。


6.脚本文件编码 utf-8 + 文件存储使用 utf-8

脚本头部显式声明脚本文件编码格式为 utf-8,同时使用 utf-8 格式存储文件:

# -*- coding: utf-8 -*-import sys
print(sys.getdefaultencoding())
print('中文')

使用 Python2.6 运行的结果如下,虽然读取正确了,但是 Python2 在 Windows 系统会默认使用 gbk 对中文进行解码,所以输出乱码:

> python26 test.py
ascii
涓枃

使用 Python3.4 运行的结果正常:

> python34 test.py
utf-8中文

结论:虽然文件存储编码和脚本文件编码都是 utf-8,但是 Windows 平台上,Python2 会按 gbk 解析中文,所以会输出乱码,可以在中文前面加 u 来解决u'中文',或者显式使用 utf-8 进行一次 decode。

汇总下验证结果,可以得到如下的表格:























不同组合下 Python3 和 Python2 处理结果Python3Python2
默认脚本文件编码 + 文件存储使用 gbkSyntaxError,解析错误SyntaxError,解析错误
脚本文件编码 gbk + 文件存储使用 gbk正常输出中文正常输出中文
脚本文件编码 utf-8 + 文件存储使用 gbkSyntaxError,解析错误正常输出中文
默认脚本文件编码 + 文件存储 utf-8正常输出中文SyntaxError,解析错误
脚本文件编码 gbk + 文件存储使用 utf-8SyntaxError,解析错误SyntaxError,编码错误
脚本文件编码 utf-8 + 文件存储使用 utf-8正常输出中文中文输出乱码

总结下结论:


  1. 如果使用 Python2 请一定要使用 gbk 格式存储文件;



  2. 如果使用 Python2 尽可能使用 gbk 存储文件且显式声明脚本文件编码为 gbk,方便后续兼容 Python3;



  3. 如果使用 Python3 不管使用什么格式存储文件,但请一定保证显式声明脚本文件编码和存储格式一致;



  4. 不管是使用 Python2 还是 Python3,保持显式声明脚本文件编码的好习惯;



  5. 如果脚本有跨平台需求,推荐使用 Python3 + 脚本文件编码 utf-8 + utf-8 格式存储文件的组合;



 

 


推荐阅读
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了数据库的存储结构及其重要性,强调了关系数据库范例中将逻辑存储与物理存储分开的必要性。通过逻辑结构和物理结构的分离,可以实现对物理存储的重新组织和数据库的迁移,而应用程序不会察觉到任何更改。文章还展示了Oracle数据库的逻辑结构和物理结构,并介绍了表空间的概念和作用。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
author-avatar
独艺无二的爱
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有