python编码问题,从隐隐作痛到除去病根

Posted toDoYourBest

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python编码问题,从隐隐作痛到除去病根相关的知识,希望对你有一定的参考价值。

 查阅的资料链接

python编码为什么这么蛋疼

python2.7手册str函数

 

 python源文件默认编码与内部默认编码

1.源文件默认编码为ASCII,所以,如果不显示声明当前代码用什么编码写的,python会用ASCII去解析,如果源文件中有UTF-8编码,由于ASCII不能翻译UTF8编码,则会报错了.

#file test.py  使用UTF8保存
a=a
b=

运行后

SyntaxError: Non-ASCII character \xe5 in file test.py on line 2, but no encodi
ng declared; see http://python.org/dev/peps/pep-0263/ for details

上面报错说character ‘\xe5‘是非ASCII码,因为‘\xe5‘是‘好‘的UTF8字节串的一部分

如下

在编码为UTF8的终端中打印
>>> a=
>>> a
\xe5\xa5\xbd

所以,当前的源文件是什么编码编辑的,一定要声明出来.比如

#coding=utf-8 #先在这里声明
#下面是程序代码

 

2.有一点需要注意的是,在终端的命令行模式编辑代码时,不需要再声明当前写代码时所用的编码,我猜是因为python在命令行模式时,直接读取当前系统的编码

例如,windows的cmd下再查看‘好‘这个字

在编码为GBK的终端(cmd)打印
>>> a=
>>> a
\xba\xc3

可以看到在cmd中,‘好‘是两个字节,不同于上的三个字节

3.内部默认编码为ASCII,导致使用一些函数时需要注意,比如str和unicode

 

 

有时候,运行一个脚本,比如我们通常用utf8编码保存脚本,如果在windows的cmd上运行,则print中文时会乱码,因为cmd的默认编码是GBK,它解释UTF8的字节串时,自然会弄的乱七八糟.

那么如何让终端打印信息时,不考虑终端的编码也不乱码?

1.调整终端默认编码

2.让脚本迎合终端的口味,要么方案a:脚本就保存为GBK的,要么方案b:在需要终端显示的地方转一下码,我说下b方案

#coding=utf-8
import sys
a=
#这个文件是保存为UTF8编码,如果要在cmd上正常显示,需要转为GBK,
aUnicode = a.decode(utf-8) #先解码为unicode,解码的时候要告诉python,a是一个utf8字节串,不要又以为是ASCII字节串
aGBK=aUnicode.encode(GBK)#将unicdode编码的a再编码为GBK
print aGBK

以上有一个小插曲,我直接用a.encode(‘GBK‘)行吗?这样是不行的,因为编码(encode)是针对unicode而言的,必须对unicode编码,如果硬生生使用类似‘我‘.encode(‘GBK‘),则会报错的

如下

>>> a=
>>> a.encode(GBK)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: ascii codec cant decode byte 0xba in position 0: ordinal
not in range(128)
>>>

看到了吧,python爬出了Unicode解码异常,python又说‘ascii‘怎么怎么样,为啥啊?

因为python只会对unicode字符串进行encode,如果非要对字节串encode,则它会先把字节串decode,也就是这样

a.encode(GBK)==(   a.decode(默认编码).encode(gbk)   )

上面的unicode解码异常,也是在进行解码的时候抛出的,python认为a就是用默认编码ASCII编码的,可a是UTF8编码啊,‘好‘在ASCII中不存在,所以会报错

3.我不管你终端什么编码,终端你都要给我正常显示.

那就用最直接的unicode编码啦,让python自己根据系统的当前编码进行转码打印出来

#coding=utf-8
print u

当 print 一个unicode字符串时,打印出来的是unicode对应的系统编码的字符,从而不会乱码了

衍生的一个小问题,我就是想看某变量unicode是啥样的,那就用reper函数(返回一个对象的字符串形式)

>>> a=u
>>> a
u\u597d
>>> print repr(a)
u\u597d

 

说一下str函数

str函数,以字符串的形式返回对象的呈现(在我理解,就是人可以看的呈现),

针对不同的对象,str有不同的操作方法,比如针对于string类型,它会原样返回

对于function类型,str函数会以字符串的形式返回这个函数在内存中的位置

string类型使用str函数时,注意一点,如果是unicode类型的字符串,一定注意当前的默认编码

如下,我在cmd,编码为GBK,python默认编码为ASCII

>>> a=u
>>> str(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeEncodeError: ascii codec cant encode character u\u597d in position 0
: ordinal not in range(128)
>>>

以上对unicode使用str函数时,这个转换涉及到默认编码内部首先进行这样的转换:unicodeStr.encode(defaultencoding).

如果defaultencoding不是编写代码本身的编码,那就会抛出异常.

所以,要设置defaultencoding,如下

>>> import sys
>>> reload(sys)
<module sys (built-in)>
>>> sys.setdefaultencoding(GBK)  #规定默认编码为GBK
>>> a=u
>>> str(a)  #这里就不会报错了
\xc0\xb2
>>> str(a)==a 
True

 

以上是关于python编码问题,从隐隐作痛到除去病根的主要内容,如果未能解决你的问题,请参考以下文章

热门从另一个片段导航到主页片段

在python 3.6中处理自定义编码时遇到类型错误

《Python从小白到大牛》第5章 Python编码规范

求帮助,编码转换的问题 python 3.4.0

常用python日期日志获取内容循环的代码片段

如何有条件地将 C 代码片段编译到我的 Perl 模块?