Python中的编码⽅式
Python中的编码⽅式
概述
在python中:编码:unicode-->str  解码:str-->Unicode
在python中,编码函数是encode(),解码函数是decode()。
【需要注意的⼀点是,如果我们调⽤de(),这⾥涉及到⼀个隐⼠的类型转化,会现将str转化成unicode,才能进⾏编码,这也是不太容易理解的地⽅。所以,de()实际上就等价于str.decode(sys.defaultencoding).encode().⽽sys.defaultencoding⼀般是ascii,它是不能⽤来编码中⽂字符的。】
各种编码⽅式
【Python中,不论是Python 2.x还是Python 3.x中,总体上说,字符都只有2⼤类:
⼀类是通⽤的Unicode字符;另⼀类是,(unicode被编码后的),某种编码类型的字符,⽐如UTF-8,GBK等等类型的字符】
ASCII(American Standard Code forInformation Interchange),是单字节编码,⼀个字节等于8位⼆进制数,所以单字节可以表
⽰256个不同的字符,可以表⽰所有的英⽂字符和许多的控制符号。不过ASCII只⽤到了其中的⼀半(\x80以下)。
MBCS(Multi-Byte Character Set) ,这⼀类编码有很多种,其中就有GBK:为了表⽰其他语⾔的字符,采⽤双字节编码,并且兼
容ASCII,采⽤的⽅式是:如果第⼀个字节是\x80以下,则仍然表⽰ASCII字符;⽽如果是\x80以上,则跟下⼀个字节⼀起(共两个字节)表⽰⼀个字符,然后跳过下⼀个字节,继续往下判断。
后来的后来·····⼈们为了⽅便统⼀了编码⽅式··unicode
Unicode的编码⽅式的标准⽤很多:【UCS-2(两个字节表⽰⼀个字符)】【UTF-8(变长的,并且兼容ASCII,ASCII字符使⽤1字节表⽰,其他符号⽤更多编码⽅式匹配)】
By the way : BOM(Byte Order Mark)是⼀种标记,就是在我们打开记事本的时候,最开始读⼊的是什么编码,我们就按这种编码⽅式打开整个⽂本,这就是为什么我们不⽤在打开记事本的时候先选择编码⽅式··
str是字节串,是它是unicode经过编码后的字节组成的序列。
例如unicode 中的“⽔”字,经过UTF-8编码后得到的str为“\xe6\xb0\xb4”len()==3
【Python中⽤中⽂字符串前⾯加上u表⽰这个字符串为unicode】
unicode是字符串,对str进过正确解码可以获得 ,对于(u“⽔”)len()==1
具体操作
"python 2.x中,普通的,⽤引号括起来的字符,就是str;此时字符串的编码类型,对应着你的Python⽂件本⾝保存为何种编码有关,最常见的Windows平台中,默认⽤的是GBK"
str->unicode:  需要解码的str.decode(解码⽅式【例如:'UTF-8'】)
unicode->str : 先声明⼀个Unicode字符unicodechar,例如【u‘⽔’】,de(编码对应的⽅式【例如:'UTF-8'】) by the way: 在python 3.x,具体操作有很⼤区别
字符码的声明:源代码⽂件中,如果有⽤到⾮ASCII字符,则需要在⽂件头部进⾏字符编码的声明,如下:
#-*- coding: UTF-8 -*-
【实际上Python只检查#、coding和编码字符串,其他的字符都是为了美观加上的。另外,Python中可⽤的字符编码有很多,并且还有许多别名,还不区分⼤⼩写,⽐如UTF-8可以写成u8。】
关于⽂件操作
内置的open()⽅法打开⽂件时,read()读取的是str
write()写⼊时,如果参数是unicode,则需要使⽤你希望写⼊的编码进⾏encode(),如果是其他编码格式的str,则需要先⽤该str的编码进⾏decode(),转成unicode后再使⽤写⼊的编码进⾏encode()。
如果直接将unicode作为参数传⼊write()⽅法,Python将先使⽤源代码⽂件声明的字符编码进⾏编码然后写⼊。
另外,模块codecs提供了⼀个open()⽅法,可以指定⼀个编码打开⽂件,使⽤这个⽅法打开的⽂件读取返回的将是unicode。写⼊时,如果参数是unicode,则使⽤open()时指定的编码进⾏编码后写⼊;如果是str,则先根据源代码⽂件声明的字符编码,解码成unicode后再进⾏前述操作。相对内置的open()来说,这个⽅法⽐较不容易在编码上出现问题。
Tips:
1.  使⽤字符编码声明,并且同⼀⼯程中的所有源代码⽂件使⽤相同的字符编码声明
2.  抛弃str,全部使⽤unicode
深⼊
正因为中⽂字符需要多个字节来表⽰,常见的正则表达式的⽂档就有可能⽆法覆盖这种情况。⽐如常见的资料都说,点号『.』可以匹配“除换⾏符\n之外的任意字符”,但这可能只适⽤于“单字节字符”
re.search('^.$', '发') == None #True
之所以会出现这种情况,是因为正则表达式⽆法正确将多个字节识别为“单个字符”
如果你细⼼就会发现,在Python 2.x中,我们指定的字符串使⽤Unicode编码,⽽⽂档⾥说了,正则表达式也可以指定Unicode模式的
正则表达式的操作可以简要概括为“⽤正则表达式去匹配字符串”,它涉及两个对象:正则表达式和字符串。
对字符串来说,如果没有设定Unicode模式,则多字节字符很可能会拆开为多个单字节字符对待(虽然它们并不是合法的ascii字
unicode码和ascii码区别
符),Python 2.x中就是如此,“发”字在没有设定Unicode编码时,变成了3个单字节字符构成的字符串,点号『.』只能匹配其中的单个“字符”。如果显式将正则表达式设定为Unicode字符串(也就是在 u'发' ),则“发”字视为单个字符,点号可以匹配。
那么对应的,如果你在正则表达式的字符组⾥使⽤了中⽂字符,表⽰正则表达式的字符串,也应该设定为Unicode字符串,否则正则表达式会认为字符组⾥不是单个字符
>>> re.search('^[我]$', u'我') == None # True
>>> re.search(u'^[我]$', u'我') == None # False
Python也可以指定正则表达式使⽤Unicode模式
不妨回头仔细想想你读过的⽂档,正则表达式中的『\d』和『\w』,都是如何解释的?或许你的第⼀反应是:『\d』等价于『[0-9]』,『\w』等价于『[0-9a-zA-Z_]』。因为有些⽂档说明了这种等价关系,有些⽂档却说:『\d』匹配数字字符,『\w』匹配单词字符。然⽽这只是针对ascii编码的规定,在Unicode编码中,全⾓数字0、1、2之类,应该也可以算“数字字符”,由『\d』匹配;中⽂的字符,应该也可以算“单词字符”,由『\w』匹配;同样的道理,中⽂的全⾓空格,应该也可以算作“空⽩字符”,由『\s』匹配。所以,如果你在Python中指定了正则表达式使⽤,『\d』、『\w』、『\s』就能匹配全⾓数字、中⽂字符、全⾓空格。
(字符均为全⾓)
>>> re.search('(?u)^\d$', u'1') == None # True >>> re.search('(?u)^\w$', u'发') == None # True >>> re.search('(?u)^\s', u' ') == None # True
如果上⾯的数字⽤半⾓,
re.search('(?u)^\d$', u'1') == None # False
参考博⽂:

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