python编码问题

本文深入探讨了Unicode与UTF-8的关系及其在Python 2.x和3.x中的应用,并讲解了字符集、编码规则及不同编码之间的转换过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 Unicode UTF-8的关系

Unicode 是「字符集

           字符集:为每一个「字符」分配一个唯一的 ID(学名为码位 / 码点 / Code Point)

UTF-8 是「编码规则」

           编码规则:将「码位」转换为字节序列的规则(编码/解码 可以理解为 加密/解密 的过程)

在Python2中,有两种字符串类型:str和unicode类型。

str存bytes数据/十六进制字节数据,unicode类型存unicode数据

# coding: UTF-8
u = '张a'
print type(u) # <type 'str'>
print repr(u) # '\xe5\xbc\xa0'
print type(u.decode('utf-8')) # <type 'unicode'>
print repr(u.decode('utf-8')) # u'\u5f20'

u = u'张a'
print type(u) # <type 'unicode'>
print repr(u) # u'\u5f20'
print type(u.encode('utf-8')) # <type 'str'> utf-8
print repr(u.encode('utf-8')) # '\xe5\xbc\xa0'
print type(u.encode('gbk')) # <type 'str'> gbk
print repr(u.encode('gbk')) # '\xd5\xc5'

为什么英文拼接成功了,而中文拼接就报错了?

这是因为在python2.x中,python解释器悄悄掩盖掉了 byte 到 unicode 的转换,只要数据全部是 ASCII 的话,所有的转换都是正确的,一旦一个非 ASCII 字符偷偷进入你的程序,那么默认的解码将会失效,从而造成 UnicodeDecodeError 的错误。python2.x编码让程序在处理 ASCII 的时候更加简单。你付出的代价就是在处理非 ASCII 的时候将会失败。

无论是utf-8还是gbk都只是一种编码规则,一种把unicode数据编码成字节数据的规则,所以utf-8编码的字节一定要用utf-8的规则解码,否则就会出现乱码或者报错的情况。

小结:

    1.str就是经过编码的字符串

    2.unicode是字符集可以转成utf-8,gbk等等

    3.编码 unicode---其他编码 ,解码  其他编码-----unicode

 

在Python3.x中,也只有两种字符串类型:str和bytes类型。

str类型存unicode数据,bytse类型存bytes数据,与python2.x比只是换了一下名字而已。

u = '张a'
print (type(u)) # <type 'str'>
print (repr(u)) # '张a'
print (type(u.encode('utf-8'))) # <class 'bytes'> utf-8
print (repr(u.encode('utf-8'))) # b'\xe5\xbc\xa0a'
print (type(u.encode('gbk'))) # <class 'bytes'> gbk
print (repr(u.encode('gbk'))) # '\xd5\xc5'

 

 

当我们在编辑文本的时候,字符在内存对应的是unicode编码的,这是因为unicode覆盖范围最广,几乎所有字符都可以显示。但是,当我们将文本等保存在磁盘时,数据是怎么变化的?

答案是通过某种编码方式编码的bytes字节串。比如utf-8,一种可变长编码,很好的节省了空间;当然还有历史产物的gbk编码等等。于是,在我们的文本编辑器软件都有默认的保存文件的编码方式,比如utf-8,比如gbk。当我们点击保存的时候,这些编辑软件已经"默默地"帮我们做了编码工作。

那当我们再打开这个文件时,软件又默默地给我们做了解码的工作,将数据再解码成unicode,然后就可以呈现明文给用户了!所以,unicode是离用户更近的数据,bytes是离计算机更近的数据。

其实,python解释器也类似于一个文本编辑器,它也有自己默认的编码方式。python2.x默认ASCII码,python3.x默认的utf-8,可以通过如下方式查询:

import sys
print(sys.getdefaultencoding())

 

 

如果我们不想使用默认的解释器编码,就得需要用户在文件开头声明了。还记得我们经常在python2.x中的声明吗?

# encoding=utf8

如果python2解释器去执行一个utf-8编码的文件,就会以默认的ASCII去解码utf-8,一旦程序中有中文,自然就解码错误了,所以我们在文件开头位置声明 #coding:utf-8,其实就是告诉解释器,你不要以默认的编码方式去解码这个文件,而是以utf-8来解码。而python3的解释器因为默认utf-8编码,所以就方便很多了。

参考资料:

       1. http://www.cnblogs.com/yuanchenqi/articles/5956943.html

       2. http://www.cnblogs.com/284628487a/p/5584714.html

       3.https://www.cnblogs.com/OldJack/p/6658779.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值