Python字符串编码——Unicode

ASCII码

我们领略,在电脑中,所有的音信最终都意味着也一个二进制的字符串。每一个二进制位(bit)有0和1少于种植状态,因此八只二进制位就可以做有256种状态,这给号称一个字节(byte)。也就是说,一个字节一共可以用来代表256种不同之状态,每一个状态对应一个符号,就是256个号,从0000000到11111111。
上个世纪60年代,美国制订了同等效字符编码,对英语字符与二进制位之间的关系,做了合并规定。这为称作ASCII码,一直沿用至今。
ASCII码一共规定了128只字符的编码,比如空格”SPACE”是32(二上制00100000),大写的字母A是65(二迈入制01000001)。这128单记号(包括32只非可知打印出来的支配符号),只占了一个字节的后7各,最前边的1位统一规定为0。

非ASCII编码

英语用128只标志编码就够了,但是就此来表示其余语言,128个号是不够的。比如,在法语中,字母上方有注音符号,它便无法用ASCII码表示。于是,一些欧洲邦就控制,利用字节中按的万丈位编入新的记号。比如,法语中之é的编码为130(二进制10000010)。这样一来,这些欧洲国行使的编码体系,可以代表最多256单记号。

然而,这里又并发了新的题材。不同的国家生不同之假名,因此,哪怕它还使256单记号的编码方式,代表的假名却无平等。比如,130以法语编码中意味着了é,在希伯来语编码中倒是表示了许母Gimel
(ג),在俄语编码中而且会代表任何一个标志。但是无论如何,所有这些编码方式中,0–127代表的标记是如出一辙的,不等同的但是128–255底当即无异于段落。

关于亚洲江山的仿,使用的号子就重多矣,汉字就是大多上10万横。一个字节只能表示256种标志,肯定是不够的,就务须用多个字节表达一个符号。比如,简体中文常见的编码方式是GB2312,使用简单只字节表示一个字,所以理论及无限多可象征256×256=65536个号。

汉语编码的题目要专文讨论,这篇笔记不干。这里只指出,虽然还是因此几近只字节表示一个符号,但是GB类的汉字编码与后文的Unicode和UTF-8是毫无关系的。

Unicode

巧使齐亦然省所说,世界上有正在多编码方式,同一个二进制数字可以被诠释成不同之标记。因此,要惦记打开一个文件文件,就必知道她的编码方式,否则用错误的编码方式解读,就见面出现乱码。为什么电子邮件时出现乱码?就是为发信人和收信人使用的编码方式不一致。

得设想,如果出同栽编码,将世界上享有的记号都纳入其间。每一个符号都给以一个举世无双之编码,那么乱码问题就会见烟消云散。这虽是Unicode,就像它的名字都意味着的,这是平等栽有符号的编码。

Unicode当然是一个百般挺之聚集,现在之面得以容纳100大抵万独记。每个符号的编码还未相同,比如,U+0639意味着阿拉伯字母Ain,U+0041意味英语的那个写字母A,U+4E25表示汉字”严”。具体的标记对应表,可以查询unicode.org,或者特别的汉字对应表。

Unicode的问题

需要留意的是,Unicode只是一个号集,它才规定了符号的次进制代码,却从未规定是二进制代码应该如何存储。

遵循,汉字”严”的unicode是十六前进制数4E25,转换成二进制数足足有15个(100111000100101),也就是说这个标记的表示至少需2独字节。表示其余还怪之号,可能得3单字节或者4单字节,甚至还多。

此处就发三三两两个沉痛的问题,第一单问题是,如何才会分Unicode和ASCII?计算机怎么亮老三独字节表示一个记,而休是独家代表三单记号为?第二单问题是,我们早已亮,英文字母只所以一个字节表示即够用了,如果Unicode统一确定,每个符号用三单或四单字节表示,那么每个英文字母前都自然产生第二及三独字节是0,这对仓储来说是特大的浪费,文本文件的高低会用大出二三加倍,这是无力回天经受的。

它造成的结果是:1)出现了Unicode的多存储方,也就是说有许多种不同的老二迈入制格式,可以就此来表示Unicode。2)Unicode在十分丰富一段时间内无法推广,直到互联网的产出。

UTF-8

互联网的普及,强烈要求出现一样种植统一之编码方式。UTF-8就是在互联网上运用最广泛的等同栽Unicode的兑现方式。其他实现方式还包UTF-16(字符用鲜个字节或四单字节表示)和UTF-32(字符用四只字节表示),不过在互联网上基本不用。重复雷同百分之百,这里的涉嫌是,UTF-8凡是Unicode的实现方式有。

UTF-8最要命的一个特色,就是它们是同一种变长的编码方式。它好运用1~4独字节表示一个记,根据不同之标记而变化字节长度。
UTF-8的编码规则不行简单,只生次长长的:

1)对于单字节的记号,字节的首先各类而为0,后面7各项呢是符号的unicode码。因此于英语字母,UTF-8编码和ASCII码是同之。

2)对于n字节的记(n>1),第一个字节的面前n位都如为1,第n+1位设为0,后面字节的前片个一律要为10。剩下的无提及的二进制位,全部吧这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的各类。

Unicode符号范围 | UTF-8编码方式

(十六进制) | (二进制)

——————–+———————————————

0000 0000-0000 007F | 0xxxxxxx

0000 0080-0000 07FF | 110xxxxx 10xxxxxx

0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx

0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

跟据上表,解读UTF-8编码非常简单。如果一个字节的率先号是0,则这字节单独就是一个字符;如果第一各类是1,则连续有小只1,就意味着手上字符占用小个字节。

下,还是坐汉字”严”为条例,演示如何实现UTF-8编码。

就知道”严”的unicode是4E25(100111000100101),根据上表,可以发现4E25地处第三执之范围外(0000
0800-0000 FFFF),因此”严”的UTF-8编码需要三个字节,即格式是”1110xxxx
10xxxxxx
10xxxxxx”。然后,从”严”的最终一个二进制位开始,依次从后上填入格式中之x,多有的各项补0。这样即使获取了,”严”的UTF-8编码是”11100100
10111000 10100101″,转换成为十六进制就是E4B8A5。

python 中的字符串编码

在使用

#!/usr/bin/env python
# -*- coding:utf-8 -*-

默认的华语编码为utf8

>>> kel = '中' 
>>> kel
'\xe4\xb8\xad'

加入u以后,变成unicode

>>> kel = u'中'
>>> kel
u'\u4e2d'

python 文件字符串编码

保存Unicode字符到文本文档

#coding=utf-8
import os

def write_use_open(filepath):
    try:
        file = open(filepath, 'wb')
        try:
            content = '中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
            print file.encoding
            print file.newlines
            print file.mode
            print file.closed
            print content
            file.write(content)
        finally:
            file.close()
            print file.closed
    except IOError, e:
        print e


if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    write_use_open(filepath)

启自己是IDLE编写的,并一直按F5运作,没发现题目,文件也给科学地保留,文件之编码类型为是utf-8.

但是我所以命令执行运行,却发现显示出现乱码了,然后以打开文件发现文件被科学保存了,编码还是utf-8:

皇冠直营现金网官方网 1

题目是令执行未可知自动识别字符编码吧,因为IDLE显示是不易的,它支持utf-8。

遂自己修改了代码,在字符串前加了’u’,表明content是unicode:
content = u’中华人民共和国abcd \r\nee
?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n’

只是运行发现,命令行是正确显示了,但是可出现异常:

皇冠直营现金网官方网 2

死肯定,content里含有了非ASCII码字符,肯定不克动用ASCII来进行编码的,write方法是默认使用ascii来编码保存的。

十分爱就好想到,在保留之前,先对unicode字符进行编码,我选择utf-8

#coding=utf-8
import os

def write_use_open(filepath):
    try:
        file = open(filepath, 'wb')
        try:
            content = u'中华人民共和国abcd \r\nee ?!>??@@@!!!!!???¥@#%@%#xx学校ada\r\n'
            print file.encoding
            print file.newlines
            print file.mode
            print file.closed
            print content
            print unicode.encode(content, 'utf-8')
            file.write(unicode.encode(content, 'utf-8'))
        finally:
            file.close()
            print file.closed
    except IOError, e:
        print e

if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    write_use_open(filepath)

瞧运行结果:

皇冠直营现金网官方网 3

OK了打开文档也是是的。
读取文件同时怎?同样道理,只是这次未是编码了,而解码:

def read_use_open(filepath):
    try:
        file = open(filepath, 'rb')
        try:
            content = file.read()
            content_decode = unicode(content, 'utf-8')
            print 'original text'
            print content
            print 'decode using utf-8'
            print content_decode
        finally:
            file.close()
    except IOError, e:
        print e

if __name__ == '__main__':
    filepath = os.path.join(os.getcwd(), 'file.txt')
    write_use_open(filepath)
    print 'read file ---------------------------'
    read_use_open(filepath)

皇冠直营现金网官方网 4

为何未直以open的上便解码呢?呵呵,可以什么,可以应用codecs的open方法

import codecs
def read_use_codecs_open(filepath):
    try:
        file = codecs.open(filepath, 'rb', 'utf-8')
        try:
            print 'using codecs.open'
            content = file.read()
            print content
        finally:
            file.close()
    except IOError, e:
        print e

皇冠直营现金网官方网 5

网络被乱码的缓解

华语网页中,有些网页抓取下来后,由于网页编码的题材,需要进行解码。首先我们得看清网页中到底使用的凡呀编码,在根据这编码把字符串变成utf8编码。

以探测编码时,chardet第三方库非常之好。

网页编码皇冠直营现金网官方网判断:

import urllib
rawdata = urllib.urlopen('http://tech.163.com/special/00097UHL/tech_datalist.js').read()
import chardet
print chardet.detect(rawdata)

{'confidence': 0.99, 'language': 'Chinese', 'encoding': 'GB2312'}

经 chardet
探测有,网页的字符编码为GB2312编码,通过unicode转化为utf8编码:

str_body = unicode(rawdata, "gb2312").encode("utf8")

还多入门教程可以参照:[http://www.bugingcode.com/python_start/]
(http://www.bugingcode.com/python_start/)

相关文章