文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

彻底搞懂 Python 编码

2023-01-31 07:43

关注

因为中文的特殊编码,导致 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 4
SyntaxError: 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 4
SyntaxError: 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:gbk

import 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 6
SyntaxError: (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 4
SyntaxError: 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:gbk
import sys

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

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

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

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

> python34 test.py
File "test.py", line 1
SyntaxError: 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 处理结果 Python3 Python2
默认脚本文件编码 + 文件存储使用 gbk SyntaxError,解析错误 SyntaxError,解析错误
脚本文件编码 gbk + 文件存储使用 gbk 正常输出中文 正常输出中文
脚本文件编码 utf-8 + 文件存储使用 gbk SyntaxError,解析错误 正常输出中文
默认脚本文件编码 + 文件存储 utf-8 正常输出中文 SyntaxError,解析错误
脚本文件编码 gbk + 文件存储使用 utf-8 SyntaxError,解析错误 SyntaxError,编码错误
脚本文件编码 utf-8 + 文件存储使用 utf-8 正常输出中文 中文输出乱码

总结下结论:

  1. 如果使用 Python2 请一定要使用 gbk 格式存储文件;
  2. 如果使用 Python2 尽可能使用 gbk 存储文件且显式声明脚本文件编码为 gbk,方便后续兼容 Python3;
  3. 如果使用 Python3 不管使用什么格式存储文件,但请一定保证显式声明脚本文件编码和存储格式一致;
  4. 不管是使用 Python2 还是 Python3,保持显式声明脚本文件编码的好习惯;
  5. 如果脚本有跨平台需求,推荐使用 Python3 + 脚本文件编码 utf-8 + utf-8 格式存储文件的组合;

本文原创发布于公众号「sylan215」,十年测试老兵的原创干货,关注我,涨姿势!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯