python的编码与解码

#########################
#  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格式编码的,就会出错
# 用print输出的时候,会忽略这个错误,打印空白
print ‘gbk_u1: ‘, u1.encode(‘gbk‘)
print ‘repr gbk_u1‘, repr(u1.encode(‘gbk‘))
try:
    # 但如果用decode()函数去解码不正确的编码字符串就会报错
    print u1.encode(‘gbk‘).decode(‘utf-8‘)
except UnicodeDecodeError as e:
    print e
print ‘‘

#########################
#    更多关于编码字符串    #
#########################

# 对解析器来说,编码字符串没什么特别的,就是一个str类型的字符串
# 可以这么理解,unicode字符串经过编码后得到了一个str类型的字符串
print ‘type of utf8_u1: ‘, type(utf8_u1)
# 和普通str字符串一样,解析器会用默认的编码来解码str字符串中的十六进制转义字符
print r"‘\xe7\x88\xb1Python‘: ", ‘\xe7\x88\xb1Python‘
# 你也可以指定编码格式
print r"‘\xe7\x88\xb1Python‘", ‘\xe7\x88\xb1Python‘.decode(‘utf-8‘)
# str字符串通过解码后得到是一个unicode字符串,哪怕是用ascii来解码
print "type of decoded ‘a‘: ", ‘a‘.decode(‘utf-8‘)
# 我们想要在str字符串中包含“\xe7”这样的字符就必须要对“\”转义
print r"‘\\xe7\\x88\\xb1Python‘: ", ‘\\xe7\\x88\\xb1Python‘
# 如果unicode字符串中包含"\xe7"字样又会怎么样呢?
print r"u‘\xe7\x88\xb1Python‘: ", u‘\xe7\x88\xb1Python‘

# 编码字符串中的十六进制转义字符表示一个字节,ascii码字符也是一个字节,
# 因此我们可以通过用len函数计算字符串编码后的编码字符串的长度的方式来得到字符串占用的字节数
print ‘length of utf8_u1: ‘, len(utf8_u1)
print ‘‘

#########################
#       字符串相连       #
#########################

# str字符串可以相连
print ‘s + s: ‘, s + s
# unicode字符串也可以直接相连
print ‘u + u1 + u2: ‘, u + u1 + u2
# 编码字符串相连时,先连接,输出时再一起解码
print ‘utf8_u1 + utf8_u2: ‘, utf8_u1 + utf8_u2
try:
    # unicode字符串和编码字符串相连的时候,系统会先用一种编码格式去解码编码字符串,
    # 如果不能正确解码编码字符串,就会报错
    print ‘u + utf8_u1 + utf8_u2: ‘,           u + utf8_u1 + utf8_u2
except UnicodeDecodeError as e:
    print e

# 但是用str字符与编码字符串相连是不会报错的
# 因为str字符的编码字符跟本身是一样的,直接加到编码字符串中不会破坏原编码字符串
# 系统会先将str字符加到编码字符串中,然后一起解码
print ‘s + utf8_u1 + utf8_u2: ‘,           s + utf8_u1 + utf8_u2

# 将编码字符串先解码再与unicode字符相连,就不会报错
print ‘decoded s + utf8_u1 + utf8_u2: ‘,           s + utf8_u1.decode(‘utf-8‘) + utf8_u2.decode(‘utf-8‘)

# 不同编码格式的编码字符串相连,是不会报错的(都是str类型嘛),但是相连后的结果就乱掉了,系统没办法解码了
print ‘repr gbk_u1 + utf8_u2: ‘, repr(u1.encode(‘gbk‘) + u2.encode(‘utf-8‘))
print ‘gbk_u1 + utf8_u2: ‘, u1.encode(‘gbk‘) + u2.encode(‘utf-8‘)

# 总结下字符串相连,要点就是:
# 同类型的直接相连;不同类型,先对unicode类型进行编码(得到str类型的编码字符串),再相连。
print ‘‘

#########################
#       文件的编码       #
#########################

u = u‘我爱Python‘
print u
print repr(u)

# 先创建一个示例文件
w = open(‘demo.txt‘, ‘w‘)
try:
    # 直接传入一个unicode字符串,可能会报错
    w.write(u)
    w.close()
except UnicodeEncodeError as e:
    # 错误原因是write()方法只接受str类型的字符串
    # 解析器会采用ascii编码去编码unicode字符
    print e
print ‘‘

# 因此我们需要先编码再写入
w.write(u.encode(‘utf-8‘))
w.close()

# 我们再把它读取出来
r = open(‘demo.txt‘, ‘r‘)
content = r.read()
r.close()

# 通过repr和type检查,我们可以看到读出来的还是str类型的编码字符串
# 而没有被转换成unicde字符串
print ‘repr content: ‘, repr(content)
print ‘type of content: ‘, type(content)
print ‘content: ‘, content

# 总结下:
# open()函数以字节为单位,从磁盘读取数据,得到str类型的文本,
# 如果某个字节不是asccii码字符,就用转义的十六进制来表示(其实也就是我们所说的编码字符串)。
# 文本在得到的file对象中都是以这种格式的str字符来处理的。这种方式规避来无法预知的编码问题,而把编码解码
# 的问题抛给调用者自己来解决。
# 因此,我们在处理从文件中读取的文本和程序中其他文本的时候要注意这点,始终记住:
# 同类型的直接相连;不同类型,先对unicode类型进行编码(得到str类型的编码字符串),再相连。

# 那么我们如果要直接处理uncode字符串怎么办?
# 用codecs模块

原文地址:https://www.cnblogs.com/gc373195040/p/9416424.html

时间: 2024-10-09 01:08:59

python的编码与解码的相关文章

python字符编码与解码 unicode,str

字符编码 计算机中的字符都是以特定的编码形式存放的,从最早的ascii到后来的Unicode以及UTF-8, 在python中, 字符串str也是是区分编码的,在各种编码的字符串之间,有一座桥梁,就是unicode类型. str, unicode str转到unicode需要解码,即decode:反之,unicode转到str需要编码,即encode: str              -- (decode) -->         unicode unicode     -- (encode)

python的编码和解码

python的机制,对于字符串str在从内存读到显示器上时,python自动完成了解码工作让你看到的不是一串二进制,而是这串二进制根据unicode对应的字符,但对于字节bytes来说,python不会对他处理,就这么原汁原味的呈现给你,所以你看到的str是字符串而bytes则是16进制表示的二进制. encode和decode 对于字符串str只有一个编码方法 .encode()默认是以utf-8编码,生成的是对应的字节bytes.也即是告诉python,str不需要自动编码了,就以二进制显示

python中编码和解码decode和encode的使用

python 在处理字符串时经常遇到编码错误,导致乱码,且python 2.x和 python 3.x之间有很大的不同,先在这里记录一下,以后整理; 转载 文章一篇: http://www.cnblogs.com/evening/archive/2012/04/19/2457440.html

python中的编码与解码

编码与解码 首先,明确一点,计算机中存储的信息都是二进制的 编码/解码本质上是一种映射(对应关系),比如‘a’用ascii编码则是65,计算机中存储的就是00110101,但是显示的时候不能显示00110101,还是要显示'a',但计算机怎么知道00110101是'a'呢,这就需要解码,当选择用ascii解码时,当计算机读到00110101时就到对应的ascii表里一查发现是'a',就显示为'a' 编码:真实字符与二进制串的对应关系,真实字符→二进制串 解码:二进制串与真实字符的对应关系,二进制

Python学习笔记八:文件操作(续),文件编码与解码,函数,递归,函数式编程介绍,高阶函数

文件操作(续) 获得文件句柄位置,f.tell(),从0开始,按字符数计数 f.read(5),读取5个字符 返回文件句柄到某位置,f.seek(0) 文件在编辑过程中改变编码,f.detech() 获取文件编码,f.encoding() 获取文件在内存中的编号,f.fileno() 获取文件终端类型(tty.打印机等),f.isatty() 获取文件名,f.name() 判断文件句柄是否可移动(tty等不可移动),f.seekable() 判断文件是否可读,f.readable() 判断文件是

Python中进行Base64编码和解码

Base64编码是一种“防君子不防小人”的编码方式.广泛应用于MIME协议,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符.优点:速度快,ascii字符,肉眼不可理解缺点:编码比较长,非常容易被破解,仅适用于加密非关键信息的场合Python中进行Base64编码和解码>>> import base64>>> s = '我是字符串'>>> a = base64.b64encode(s)>>>

从Python的角度来看编码与解码

导语: Python2和Python3中,因为默认字符集的不同而造成的麻烦,简直是程序员的梦魇!要彻底告别这个麻烦,就需要从本质上来理解编码和解码. 为什么要有编码? 对于不会英文的中国人来说,将英文翻译成中文,这个就叫做解码:而将中文翻译成英文,自然就是编码了! 这个道理在计算机中同样适用. 计算机只能识别0和1,任何文字对于计算机来说,就是0和1的排列组合.但是我们人类哪看得懂这种0和1的排列组合! 自然就需要将0和1的文字转换为我们能看得懂的文字,比如中文,英文等. 而这种0和1到文字的映

python第三天学习复习,集合set,文件操作,函数(普通函数,递归,高阶函数),字符编码和解码

三元运算 age = 23 #就是if else的简单写法 a = age if age < 20 else 25 集合 set #集合是无序切不重复的, #当对列表去重复的时候,可以直接使用 set(list),就将list转为set,并去除中间重复的 list = [1,2,3,4,5,5,6,7,8,9,1] s = set(list) 运行结果:可以发现将 list中重复的去掉,并且类型变成set,再使用list(set),转为list 集合操作 # Author:zylong set1

python之is 和 == 的区别//编码和解码

一.is  和  ==  的区别: ==   比较    #比较两边的值 is    比较   #比较的是内存地址 id()是python的一个内置函数,通过id()我们可以查到一个变量表的值在内存中的地址 (只限于数字和字符串是True) #数字小数据池 :    -5~256 1.字符串中如果有特殊字符,那么不会添加到小数池中,他们的内存地址就不一样 字符串中单个*20以内他们的内存一样,超过20个就不会添加到小数据池;单个*以上内存地址就不一样 注意:pycharm是个坑,一个py文件中所