Python中⽂编码问题(字符串前⾯加‘u‘decodeencode)
⽂章⽬录
1. 前⾔
我们知道,计算机是以⼆进制为单位的,也就是说计算机只识别0和1,也就是我们平时在电脑上看到的⽂字,只有先变成0和1,计算机才会识别它的意思。这种数据和⼆进制的转换规则就是编码。计算机的发展中,有ASCII码,GBK,Unicode,utf-8编码。我们先从编码的发展史了解⼀下编码的进化过程。
2. 编码发展史
美国⼈发明了计算机,⽤⼋位0和1的组合,⼀⼀对应英⽂中的字符,整出了⼀个表格,ASCII表。
计算机传⼊中国,中国地⼤物博,繁体字和简体字多,8位字节最多表⽰256个字符,满⾜不了,于是对ASCII扩展,新表叫GB2312后来发现GB2312还不够⽤,扩充之后形成GB18030。
每个国家都像中国⼀样,把⾃⼰的语⾔编码,于是出现了各种各样的编码,如果你不安装相应的编码,就⽆法解释相应编码想表达的内容。
各⾃编码⽆法国际交流。⼀个国际组织⼀起创造了⼀种编码 UNICODE(Universal Multiple-Octet Coded Character Set)规定所有字符⽤两个字节表⽰,就是固定的,所有的字符就两个字节,计算机容易识别。2的16次⽅可以表⽰所有的字符了。
UNICODE虽然解决了各⾃为战的问题,但是美国⼈不愿意了,因为美国原来的ASCII只需要⼀个字节就可以了。UNICODE编码却让他们的语⾔多了⼀个字节,⽩⽩浪费⼀个字节的存储空间。经过协商,出现了⼀种新的转换格式,被称为通⽤转换格式,也就是
UTF(unicode transformation format).常见的有utf-8,utf-16。utf-8规定,先分类,美国字符⼀个字节,欧洲两个字符,东南亚三个字符。
3. encode()和decode()
decode英⽂意思是 解码,encode英⽂原意 编码
unicode码和ascii码区别字符串在Python3内部的表⽰是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码, 即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另⼀种编码。
decode的作⽤是将其他编码的字符串转换成unicode编码,如str1.decode(‘gb2312’),表⽰将gb2312
编码的字符串str1转换成unicode编码。
encode的作⽤是将unicode编码转换成其他编码的字符串,如de(‘gb2312’),表⽰将unicode编码的字符串str2转换成
gb2312编码。
总得意思:想要将其他的编码转换成utf-8必须先将其解码成unicode然后重新编码成utf-8,它是以unicode为转换媒介的 如:s=‘中⽂’ 如果是在utf8的⽂件中,该字符串就是utf8编码,如果是在gb2312的⽂件中,则其编码为gb2312。这种情况下,要进⾏编码转换,都需要先⽤ decode⽅法将其转换成unicode编码,再使⽤encode⽅法将其转换成其他编码。通常,在没有指定特定的编码⽅式时,都是使⽤的系统默认编码创建的代码⽂件
4. 有哪些处理⽅式?
中⽂编码问题是⽤中⽂的程序员经常头⼤的问题,在python下也是如此,那么应该怎么理解和解决python的编码问题呢?
我们要知道python内部使⽤的是unicode编码,⽽外部却要⾯对千奇百怪的各种编码,⽐如作为中国程序经常要⾯对的
gbk,gb2312,utf8等,那这些编码是怎么转换成内部的unicode呢?
⾸先我们先看⼀下源代码⽂件中使⽤字符串的情况。源代码⽂件作为⽂本⽂件就必然是以某种编码形式存储代码的,python2默认会认为源代码⽂件是asci编码,⽐如说代码中有⼀个变量赋值:
s1=’a’
print s1
python2认为这个’a’就是⼀个asci编码的字符。在仅仅使⽤英⽂字符的情况下⼀切正常,但是如果⽤了中⽂,⽐如:
print s1
这个代码⽂件被执⾏时就会出错,就是编码出了问题。python默认将代码⽂件内容当作asci编码处理,但asci编码中不存在中⽂,因此抛出异常。
解决问题之道就是要让python知道⽂件中使⽤的是什么编码形式,对于中⽂,可以⽤的常见编码有utf-8,gbk和gb2312等。只需在代码⽂件的最前端添加如下:
# -*- coding: utf-8 -*-
这就是告知python我这个⽂件⾥的⽂本是⽤utf-8编码的,这样,python就会依照utf-8的编码形式解读其中的字符,然后转换成unicode 编码内部处理使⽤。
不过,如果你在Windows控制台下运⾏此代码的话,虽然程序是执⾏了,但屏幕上打印出的却不是哈字。这是由于python编码与控制台编码的不⼀致造成的。Windows下控制台中的编码使⽤的是gbk,⽽在代码中使⽤的utf-8,python按照utf-8编码打印到gbk编码的控制台下⾃然就会不⼀致⽽不能打印出正确的汉字。
解决办法⼀个是将源代码的编码也改成gbk,也就是代码第⼀⾏改成:
# -*- coding: gbk -*-
另⼀种⽅法是保持源码⽂件的utf-8不变,⽽是在’哈’前⾯加个u字,也就是:
s1=u’哈’
print s1
这样就可以正确打印出’哈’字了。
这⾥的这个u表⽰将后⾯跟的字符串以unicode格式存储。python会根据代码第⼀⾏标称的utf-8编码识别代码中的汉字’哈’,然后转换成unicode对象。如果我们⽤type查看⼀下’哈’的数据类型type(‘哈’),会得到<type ‘str’>,⽽type(u’哈’),则会得到<type ‘unicode’>,也就是在字符前⾯加u就表明这是⼀个unicode对象,这个字会以unicode格式存在于内存中,⽽如果不加u,表明这仅仅是⼀个使⽤某种编码的字符串,编码格式取决于python对源码⽂件编码的识别,这⾥就是utf-8。
Python在向控制台输出unicode对象的时候会⾃动根据输出环境的编码进⾏转换,但如果输出的不是unicode对象⽽是普通字符串,则会直接按照字符串的编码输出字符串,从⽽出现上⾯的现象。
使⽤unicode对象的话,除了这样使⽤u标记,还可以使⽤unicode类以及字符串的encode和decode⽅法。
unicode类的构造函数接受⼀个字符串参数和⼀个编码参数,将字符串封装为⼀个unicode,⽐如在这⾥,由于我们⽤的是utf-8编码,所以unicode中的编码参数使⽤’utf-8′将字符封装为unicode对象,然后正确输出到控制台:
s1=unicode(‘哈’, ‘utf-8′)
print s1
另外,⽤decode函数也可以将⼀个普通字符串转换为unicode对象。很多⼈都搞不明⽩python字符串的decode和encode函数都是什么意思。这⾥简要说明⼀下。
decode是将普通字符串按照参数中的编码格式进⾏解析,然后⽣成对应的unicode对象,⽐如在这⾥我们代码⽤的是utf-8,那么把⼀个字符串转换为unicode就是如下形式:
s2=’哈’.decode(‘utf-8′)
这时,s2就是⼀个存储了’哈’字的unicode对象,其实就和unicode(‘哈’, ‘utf-8′)以及u’哈’是相同的。
那么encode正好就是相反的功能,是将⼀个unicode对象转换为参数中编码格式的普通字符,⽐如下⾯代码:
s3=unicode(‘哈’, ‘utf-8′).encode(‘utf-8′)
s3现在⼜变回了utf-8的’哈’。
# 字符串在Python3内部的表⽰是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,
# 即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另⼀种编码。
a = u"中国"
print a
print a.decode('utf-8')# 报错:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) UnicodeEncodeError:'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)
# coding=utf-8
a = u"中国"
b ="哈哈"
# decode中的参数coding必须是b原来的编码⽅式,
# b.decode('utf-8')就是对原来是utf-8编码的b解码为unicode编码。
print b.decode('utf-8')
de('utf-8')
# encode中的参数coding必须是a即将要编码的⽅式,
# a.encode('utf-8') 就是要对原来是unicode编码的a进⾏utf-8编码。
附录
Python2和Python3有哪些区别|全⾯总结|专业避坑——编码问题

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。