#########################
# Python中的字符类型 #
#########################
# Python中的字符类型分两种:
# 1. str类型:ascii表中的字符,占一个字节,所以也叫字节字符。字面量用双引号表示。 # 2. unicode类型:一个字符串占用的字节数由保存时采用的编码格式相关。字面量用带“u”前缀的双引号表示。 s = 'OK, ' u = u'我, ' u1 = u'我' u2 = u'爱Python' print 's:', s print 'u1:', u1 print 'u2:', u2 # 解析器通常把unicode字符转换成Unicode转义序列 # 转义序列以"\u"开头 print 'repr(s): ', repr(s) print 'repr(u1): ', repr(u1) print 'repr(u2): ', repr(u2) # 这种转义序列只在unicode字面量中有效 print "'\u6211': ", '\u6211' print "u'\u6211': ", u'\u6211' print '' # 也可以用str()函数创建str字符串,用unicode()函数创建unicode字符串 print 'type of str(s): ', type(str(s)) print 'type of unicode(s): ', type(unicode(s)) # 可以给unicode()函数传入一个unicode字符串 print 'type of unicode(u): ', type(unicode(u)) # 但是如果我们给unicode()函数传入'我',又会怎样呢? try: print "unicode('我'):", unicode('我') except UnicodeDecodeError as e: # 错误信息 # 解析器试图用ascii编码来解码我们传入的参数,原因会在下面将到 print e ######################### # 编码和解码 # ######################### # 编码的过程其实就是采用一定的编码格式将unicode字符转换成str字符的过程 # 非ascii码字符按字节为单位被编码成十六进制转义字符 # 解码采用的编码格式跟设置和环境有关 utf8_s = s.encode('utf-8') utf8_u = u.encode('utf-8') utf8_u1 = u1.encode('utf-8') utf8_u2 = u2.encode('utf-8') print 'utf8_s: ', s print 'repr utf8_u: ', repr(s) print 'utf8_u: ', u print 'repr utf8_u: ', repr(utf8_u) print 'utf8_u1: ', utf8_u1 print 'repr utf8_u1: ', repr(utf8_u1) print 'utf8_u2:', utf8_u2 print 'repr utf8_u2: ', repr(utf8_u2) # 如果我们的str字面量中有非ascii码字符,解析器会自动对其进行编码 print "'我爱Python': ", '我爱Python' print "repr '我爱Python': ", repr('我爱Python') # 来看看上面碰到的问题,我们将带‘我’(str类型)传给unicode函数,结果报错了 try: print "unicode('我'):", unicode('我') except UnicodeDecodeError as e: # 发生错误了,解析器试图用ascii编码来解码我们传入的参数 print e # 原因就是解析器会先将参数用默认的编码格式(这里是utf-8)进行编码,然后传给unicode()函数, # unicode函数的帮助信息,其中有段是这么说的: '''unicode(string[, encoding[, errors]]) -> unicode object | | Create a new Unicode object from the given encoded string. | encoding defaults to the current default string encoding. ''' # unicode类总会用第二个参数指定的编码格式来解码第一个参数,如果第二个参数为空,就采用默认的格式。 # 脚本开头指定了utf-8编码格式,因此这里传入的‘我’被自动采用utf-8进行编码。 # 可是这里unicode并没有采用我们开头指定的utf-8格式来解码,而是ascii码,那当然会报错。 # 为什么会采用ascii码,我估计原因是这样的,Python 2.7.x在解析器内都是默认采用ascii作为默认编码格式的, # 而我们在文件开头指定的utf-8格式只对本文件中的字符串字面量有效,而unicode类是定义在其他的模块文件里。 # 我们在文件开头用了“coding: utf-8”指定了编码格式, # 因此解析器会采用这个格式去解码本文件中碰到的编码字符串 # 如果这个编码字符串不是用utf-8格式编码的,就会出错