软件测试学习 之 Python coding:utf-8和setdefaultencoding

本文主要是针对python2,为了支持中文,必须指定文件编码或者字符串默认编码的问题进行更一步阐述
python3由于字符串采用unicode编码,文件默认编码为UTF-8,不再需要添加声明或者指定字符串编码

coding:utf-8和setdefaultencoding区别

1. # coding:utf-8

作用是声明编码格式,定义源代码的编码. 如果没有定义, 此源码中是不可以包含中文字符串的.

PEP 0263中对此有详细说明(下文有相关内容的翻译)
PEP 0263 -- Defining Python Source Code Encodings
https://www.python.org/dev/peps/pep-0263/

2. sys.getdefaultencoding()

设置默认的string的编码格式

import sys
reload(sys)
sys.setdefaultencoding('utf8')

而python2.x的的defaultencoding是ascii,这也就是大多数python编码报错的原因

“UnicodeDecodeError: 'ascii' codec can't decode byte ......”

 

编码声明:是coding:utf-8还是coding=urf-8

我们知道在Python源码的头文件中要声明编码方式,之所以要声明未编码类型 ,主要是中文出错的问题。如果你不只是会用到ascii码,很多人都写得都有点差别:

# coding=utf-8
# coding:utf-8
# -*- coding:utf-8 -*-

那么怎样写才是有效地呢,哪些是无效的呢? 

这可以查看下http://www.python.org/dev/peps/pep-0263/的解释

概要:

    这个PEP的目的是介绍在一个Python源文件中如何声明编码的语法。随后Python解释器会在解释文件的时候用到这些编码信息。最显著的是源文件中对Unicode的解释,使得在一个能识别Unicode的编辑器中使用如FUT-8编码成为可能

怎么声明呢?

如果在Python中我们并没有声明别的编码方式,就是以ASCII编码作为标准编码方式的
为了定义源文件的编码方式,一个魔法是的声明应当被放在这个文件的第一行或者是第二行例如:

#coding=<encoding name>

或者(使用流行编辑器中的格式化方式)

#!/usr/bin/python 
# -*- coding: <encoding name> -*-

或者

#!/usr/bin/python
# vim: set fileencoding=<encoding name> :

不管怎么样,这些在第一行或者第二行的声明都要符合正则表达式 

 "coding[:=]\s*([-\w.]+)"

示例

    下面是一些示例,在Python源文件顶部,声明的源代码编码所采用的不同样式

    1. 指定执行脚本的解释器,并使用Emacs风格的文件编码注释:

  #!/usr/bin/python
  # -*- coding: latin-1 -*-
  import os, sys
  ...
  #!/usr/bin/python
  # -*- coding: iso-8859-15 -*-
  import os, sys
  ...
  #!/usr/bin/python
  # -*- coding: ascii -*-
  import os, sys
  ...

    2. 不指定解释器,使用注释语句:

  # This Python file uses the following encoding: utf-8
  import os, sys
  ...

    3. 各种文本编辑器可能有不同的方法来定义文件的编码,例如。

  #!/usr/local/bin/python
  # coding: latin-1
  import os, sys
  ...

    4. 如果不编码注释,Python的解析器将默认为ASCII文本:

  #!/usr/local/bin/python
  import os, sys
  ...

    5. 以下是一些无效的编码声明:

      没有 "coding:" 前缀:

  #!/usr/local/bin/python
  # latin-1
  import os, sys
  ...

       编码声明没有在第一行和第二行:

  #!/usr/local/bin/python
  #
  # -*- coding: latin-1 -*-
  import os, sys
  ...

       不支持的编码类型:

  #!/usr/local/bin/python
  # -*- coding: utf-42 -*-
  import os, sys
  ...

 

以上几个例子充分说明了哪些是正确的写法,哪些是正确的写法

所以我们就可以知道为什么使用冒号coding:或者等号coding=都可以了,如果声明的编码python不能识别就会报错

python 支持3种编码声明中,一般常用能见到前两种

# -*- coding: utf-8 -*-    这种写法是为了兼容Emacs的编码声明

# coding=utf-8    短一点,但Emacs不能用

这里要注意的是:

  • coding 后面使用 ":" 或 "=" 都可以
  •  coding和":" 或 "=" 必须之间没有空格。至于 ":" 或 "=" 后面,有没有空格都可以。

 

为什么有时候必须添加sys.setdefaultencoding('utf-8')

Python 里面的编码和解码也就是 unicode 和 str 这两种形式的相互转化。

编码是 unicode -> str,相反的,解码就是 str -> unicode。

关于文件开头的"编码指示",也就是 # -*- coding: -*- 这个语句。Python 默认脚本文件都是 UTF-8 编码的,当文件中有非 UTF-8 编码范围内的字符的时候就要使用"编码指示"来修正.

至于sys.defaultencoding,这个在解码时没有明确指明解码方式的时候使用。比如如下代码: 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
s = '中文'  # 注意这里的 str 是 str 类型的,而不是 unicode 
s.encode('gb18030') 

这句代码将 s 重新编码为 gb18030 的格式,即进行 unicode -> str 的转换。因为 s 本身就是 str 类型(python2字符串默认不是unicode)的,因此 Python 会自动的先将 s 解码为 unicode ,然后再编码成 gb18030。因为解码是python自动进行的,我们没有指明解码方式,python 就会使用 sys.defaultencoding 指明的方式来解码。很多情况下 sys.defaultencoding 是 
ANSCII
,如果 s 不是这个类型就会出错。拿上面的情况来说,我的sys.defaultencoding是anscii,而 s 的编码方式和文件的编码方式一致,是 utf8 的,所以出错了: 
“UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 0: ordinal not in range(128) "
对于这种情况,我们可以在字符串前加u将s直接指定为unicode字符串,

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
s = u'中文'  # 注意这里的s是unicode字符,不需要再解码
s.encode("GB18030") 

一般情况下,从文件或者网络中获取字符串是无法直接指定为unicode的,
这种时候,可以通过以下两种方法来解决: 
一、明确的指示出 s 的编码方式 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
s = '中文' 
s.decode('utf-8').encode('gb18030') 

二、更改 sys.defaultencoding 为文件的编码方式 

#! /usr/bin/env python 
# -*- coding: utf-8 -*- 
import sys 
reload(sys)  # Python2.5 初始化后会删除 sys.setdefaultencoding 这个方法,我们需要重新载入 
sys.setdefaultencoding('utf-8') 
str = '中文' 
str.encode('gb18030')

以上内容根据以下博主的文章整理

--------------------- 
作者:suibianshen2012
来源:CSDN 
原文:python中coding:utf-8和setdefaultencoding区别

作者:wlwxww 
来源:CSDN 
原文:为什么有时候必须添加sys.setdefaultencoding('utf-8')

作者:不笑猫 
来源:CSDN 
原文:python文件编码说明 coding=utf-8

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值