• 1
  • 3
分享
  • 【原创】Python2 和 Python3 中默认编码的差异
  • sylan215 2018-09-17 12:12:38 字数 3047 阅读 1412 收藏 3

最近在使用 Python3.4 做一些脚本实现,发现对于编码的处理上和 Python2.6 有很大的不同,就此机会把相关知识做个梳理,方便需要的时候查阅。
先说下概念和差异:

脚本字符编码:就是解释器解释脚本文件时使用的编码格式,可以通过 # -\*- coding: utf-8 -\*- 显式指定
解释器字符编码:解释器内部逻辑过程中对 str 类型进行处理时使用的编码格式
Python2 中默认把脚步文件使用 ASCII 来处理(历史原因请 Google)
Python2 中字符串除了 str 还有 Unicode,可以用 decode 和 encode 相互转换
Python3 中默认把脚步文件使用 UTF-8 来处理(终于默认就支持中文了,赞)
Python3 中文本字符和二进制分别使用 str 和 bytes 进行区分,也是使用 decode 和 encode 进行相互转换

关于默认脚本字符编码,因为对脚步文件处理的默认编码格式变了,所以很多针对内容的处理,都发生了变化,比如下面这个脚本。

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

使用 Python3.4 解释器运行结果如下:

> python34 test.py
utf-8
中文

使用 Python2.6 解释器运行结果如下:

> 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

使用 Python2.6 报错就是因为第一条说的「Python2 中默认把脚步文件使用 ASCII 来处理」,但是脚步文件包含了中文,ascii 又没有覆盖中文,所以报错。如果我们把脚步稍作修改:

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

增加了脚本字符编码的说明,再次使用 Python2.6 解释器运行结果为:

> python26 test.py
ascii
涓枃

因为明确指定了脚步文件编码格式为 utf-8,所以读取没问题,也就是说如果 Python2 脚本文件中包含了非 ASCII 字符时,一定要显式指定脚步文件编码格式,对于 Python3 因为默认的脚步文件编码格式就是 utf-8,所以没有这个问题(后面会有文章详细讨论这个问题)。
但是我们回头看下刚才的输出,结果显示为乱码。
乱码就涉及到另一个我们要说的不同点解释器字符编码,因为我们定义了 utf-8 格式读取脚步内容,但是因为 Python2.6 在 Windows 平台上,默认是使用 gbk 对字符进行 decode 输出,不信你看:

> python26
ActivePython 2.6.6.15 (ActiveState Software Inc.) based on
Python 2.6.6 (r266:84292, Aug 24 2010, 16:01:11) [MSC v.1500 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> s='中文'
>>> s
'\xd6\xd0\xce\xc4'
>>> s.decode('gbk').encode('utf-8')
'\xe4\xb8\xad\xe6\x96\x87'
>>> print('\xd6\xd0\xce\xc4')
中文
>>> print('\xe4\xb8\xad\xe6\x96\x87')
涓枃

完整描述下上面乱码出现的过程:
使用指定的脚本文件编码 utf-8 格式读取了「中文」,读取到的字符串内容为 ‘\xe4\xb8\xad\xe6\x96\x87’,然后输出时 Python2.6 的解释器使用默认解释器字符编码 gbk 格式对读取内容进行 encode 输出,但是之前 utf-8 是 3 个字节长度表示一个中文,而 gbk 是用 2 个字节长度来表示中文,所以之前的 2 个中文,在输出的时候就按照 3 个中文进行编码(encode),当然就乱码了,仔细看那个乱码,就是 3 个字。
我们再用代码验证下上面说的内容:

# -*- coding: utf-8 -*-
import sys
print(sys.getdefaultencoding())
print('中文')
print('\xe4\xb8\xad\xe6\x96\x87')
print('\xe4\xb8\xad\xe6\x96\x87'.decode('gbk', 'ignore'))
print('\xd6\xd0\xce\xc4'.decode('gbk').encode('utf-8'))
print('中文'.decode('utf-8'))
print('\xe4\xb8\xad\xe6\x96\x87'.decode('utf-8'))
print('\xd6\xd0\xce\xc4')
print('\xd6\xd0\xce\xc4'.decode('gbk'))

看看输出结果:

> python26 test.py
ascii
涓枃
涓枃
涓枃
涓枃
中文
中文
中文
中文

很明显 gbk 格式解码的十六进制字符正常输出为中文了,显式使用 utf-8 对 utf-8 格式的十六进制字符进行 decode 也输出正常了。
同理,还可以看到另外 2 个现象:

把 py 文件用 utf-8 格式存储,并且包含「中文」字样时,如果使用 gbk 格式打开,也是看到「中文」显示的乱码和上面程序输出的一致;
如果把 py 文件使用 gbk 格式存储,这时候 print('中文') 也显示正常了;

乱码的终极原因就是:对同一个字符串的 encode 和 decode 编码格式不一致。
上面说的这个问题,如果文件存储和脚本文件编码都使用 utf-8 时,使用 Python3.4 是没有问题的,因为 Python3 默认的解释器字符编码是 utf-8 了,默认就可以处理中文了。

总结下结论:

  1. Python2 脚步文件尽量使用 gbk 格式存储;同理 Python3 脚步文件尽量使用 utf-8 格式存储;
  2. Python2 脚步如果带有中文字符时,请务必在脚本开头声明能支持中文的脚本文件编码;
  3. Python2 中对同一个字符串的 encode 和 decode 编码格式请保持一致;
    说明:本次所有测试脚本文件均保存为 utf-8 格式

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

  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          • 一. 我们没有已经部署的环境,其他团队会做这件事情你星期一早上来办公室。您注意到生成拦截器有几个问题。您需要从构建存储库构建新版本。您提出请求或联系您的开发团队或部署团队。哦,他们都在忙些其他的事情。但他们在一段时间后就可以做到了。现在告诉我,为什么会这样?它并不像看上去那么复杂。当采取新的构建时,开发人员肯定肯定可以修复好。但是,当您只需触发并部署它时,为什么要等待或依赖某个人呢?有能力和权限随时部署,使您的工作更容易,没有任何等待。你看到了吗?它也会增加你每天测试的周转时间。尽管它正在使用添加的记录器调试某些缺陷,或者使用新的构建来验证已解决的错误。或者是进行新的构建并开始测试新...
            0 0 726
            分享
          • selenium 中隐藏元素如何定位?面试题:selenium 中隐藏元素如何定位?这个是很多面试官喜欢问的一个题, 如果单纯的定位的话,隐藏元素和普通不隐藏元素定位没啥区别,用正常定位方 法就行了但是吧~~~很多面试官自己都搞不清楚啥叫定位,啥叫操作元素(如 click,clear,send_keys)隐藏元素如下图有个输入框和一个登录的按钮,本来是显示的面试 web 自动化必然会问到 selenium,问 selenium 相关的问题定位是最基本的, 也是自动化的根本,所以面试离不开元素定位问题。 之前看到招聘要求里面说“只会复制粘贴 xpath 的就不要投简历了”,说明面试 官对求职者的...
            0 0 1253
            分享
          •   Pytest简介  Pytest is a mature full-featured Python testing tool that helps you write better programs.The pytest framework makes it easy to write small tests, yet scales to support complex functional testing for applications and libraries.  通过官方网站介绍我们可以了解到,pytest是一个非常成熟的全功能的python测试框架,主要有以...
            0 0 512
            分享
          •   在软件测试这条道路上,大部分的职业技能发展道路都会是纯业务手工测试→自动化测试→性能测试→安全测试/测试开发。  但是却有着一部分人起初进入软件测试这一行看重的就是软件测试属于IT行业,门槛比较低,不需要代码基础。  这就导致了这一部分测试工程师在一定程度上,在职位上的进阶就比较困难了。因为现在基本绝大多数互联网公司都已经把代码编程和自动化作为必要的技能。  为了更好的解决这部分工程师的工作痛点,本文分享一款近几年非常火爆的一款自动化测试工具:Katalon Studio。  1. Katalon Studio介绍  Katalon Studio 是一款在网页应用、移动和网页服务...
            0 0 337
            分享
          •   我也是黑盒出来的呀  现在我到一家公司,就会有小朋友问我:你以前是开发吗?你是怎么变厉害的呀?到底要怎么学习呀?  我也是黑盒出来的呀,不要小看测试的能力的嘛~  很幸庆的是,我是计算机专业出来的,这个基础给我带来了很多的优势;其实很多时候,我自己也是在后悔,出来的一刹那为什么没有选择去成为一名研发,而选择了测试。  其实,越到后面越会明白,如果一开始是研发而转为测试开发,那会容易些。  为什么一开始的时候没有选择去编码呢?同样的思路:大学的时候真的不喜欢编码,觉得测试入门简单,动代码的机会比较少;可是哇!工作后,为了涨薪,硬生生的逼自己学会了编码~~汗~~  我从功能转自动化的过程  我...
            0 0 535
            分享
      • 51testing软件测试圈微信