在用python编程中,字符串有两种表示方法"string"和 u"string"。
为什么字符串要是用这两种表达方式。不是仅仅用前一种呢?
使用type()函数查看,它们各自是str对象和unicode对象。这两个对象有什么差别吗?还有经经常使用到的encode()和decode()又是干什么的呢?都说python脚本使用的是两字节编码,这又是指什么呢?
Character Set:字符集,是我们人能够识别的字符。如ASCII规定了127个用一个字节能够表示的字符集。包含英文字母、数字、符号和一些控制字符。当然ASCII定义的字符集比較小。
python中的Character Set基本包含眼下世界上全部是用的字符。如中文、英文、日文字符等等。所以基本上全部的字符都可在Python 中进行处理。
Code Point :计算机是不能直接识别字符的(由于它仅仅能直接识别二进制码),所以为了能让计算机处理和存储字符,须要将字符映射成一个数值(由于数值能够用二进制表达,计算机从而就能够识别了),这个数值叫作字符的code point。字符与其code point是一对一映射,Unicode非常好的规定了这样的映射关系。Encode:unicode尽管规定了每一个字符的Code Point,但并没有规定计算机怎样存储这些Code Point。全部就有了UTF-8、GBK、UTF-16等编码格式,它们规定计算机怎样来存储这个Code Point,每一个编码格式它们存储方式都是不同样的。比如,“中”字的Code Point为U
+2D2E(U表示Unicode,2D2E表示该Code Point值),使用GBK、Big5、UTF-8、UTF-16四种编码协议对该Code Point进行编码。获得的实际二进制表演示样例如以下:GBK Big5 UTF-8 UTF-16 ~~\xD6\xD0 \xA4\xA4 \xE4\xB8\xAD \x2D\x4EDecode:对实际的二进制进行解码。获取它所代表字符的Code Point。如“\xD6\xD0”使用GBK解码,将获得2D2E(“中”的Code Point ),假设使用UTF-8对其进行解码。就会出错。由于它不是用UTF-8编码的。
unicode对象用来表示字符。它不涉及字符的底层的二进制编码信息。
str对象是用来表示字符的二进制信息。一个unicode对象能够使用多种编码格式(如UTF8、GBK)编码(encode)成多个str对象。每一个str对象表示该字符串的一种二进制表达。多个不同的str对象能够解码成相等的unicode对象(表示字符串同样。但内存位置不同)。
unicode尽管不规定详细的二进制信息,但为了存放每一个字符的Code Point值,须要两个字节,所以说Python採用的是二进制编码(不知道这么理解可对?)。
假设编码不匹配,就会出现乱码或者报错。
称字符串,它是字符串使用特定编码格式进行编码后的二进制表达,实际代表用于存储二进制信息的字节串。所以称它为“字节串”更合适。如
>>> str = '你好' #採用系统设定的编码格式对“你好”进行编码,可通过locale命令查看。 >>> str '\xe4\xbd\xa0\xe5\xa5\xbd' #当locale设置为utf8时。'你好'的编码后的二进制表达,一个六字节的字节串
Unicode对象:
用于表达“字符”,由于计算机不用直接识别字符,所以使用Code Point来取代字符。例如以下:
>>> u"你好" u'\u4f60\u597d'
Code Point 4F60表示“你”,597d表示“好”。它仅仅是一个数值与字符映射,
不用于详细编码。
以下运行一个str对象从utf8格式到gbk格式的转换:
>>> str="你好" >>> str '\xe4\xbd\xa0\xe5\xa5\xbd' # 採用OS的utf8编码格式 >>> unicode=str.decode("utf8") # 解码成Code Point值 >>> unicode u'\u4f60\u597d' >>> str_gbk=unicode.encode("gbk") # 将Code Point编码成GBK格式 >>> str_gbk '\xc4\xe3\xba\xc3' >>> unicode.encode() # 假设编码不指定格式,将採用系统默认的编码格式进行编码。对于decode也一样。这里因为ASCII不能对中文字符编码,所以出错了。 Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) >>> u = u"你好" #前缀u自己主动把字符串从utf8转换成unicode格式了 u'\u4f60\u597d'
>>> file=open("test.txt", "a") >>> file.write(str) >>> file.write(str_gbk) >>> file.write(unicode) Traceback (most recent call last): File "<stdin>", line 1, in <module> UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)从上面看。UTF8格式的str对象和GBK格式的str对象成功的写入test.txt文件,然而在将unicode对象写入文件时。出现错误了。
这是为什么呢?
然后unicode对象表示的是字符串的Code Point值,是抽象的值,用来表示字符,是不能直接写入文件的。所以Python试图使用默认的编码格式ASCII。对unicode对象进行编码,然后将结果存入文件。可是因为ASCII不能对”你好”进行编码,所以报错了。
>>> import sys >>> reload(sys) <module 'sys' (built-in)> >>> sys.setdefaultencoding("gbk") #不建议这么用[2] >>> str(unicode) #使用默认GBK,对unicode("你好")进行编码,转成str对象 '\xc4\xe3\xba\xc3' >>> unicode.encode() #使用默认GBK。对unicode("你好")进行编码,转成str对象 '\xc4\xe3\xba\xc3' >>> "你好".decode() #由于系统使用UTF8,所以“你好”是UTF8格式的字节串,使用默认GBK对该字节串进行解码,尽管成功执行了,但其结果是不对的。所以我们须要保证字节串用什么格式编码的。就要用什么格式解码。 u'\u6d63\u72b2\u30bd'
bid=284&id=84741
来源:https://www.cnblogs.com/mfrbuaa/p/5077643.html