python编码与解码

python字符串前面加u,r,b的含义
u/U:表示unicode字符串
不是仅仅是针对中文, 可以针对任何的字符串,代表是对字符串进行unicode编码。
一般英文字符在使用各种编码下, 基本都可以正常解析, 所以一般不带u;但是中文, 必须表明所需编码, 否则一旦编码转换就会出现乱码。
建议所有编码方式采用utf8

r/R:非转义的原始字符串
与普通字符相比,其他相对特殊的字符,其中可能包含转义字符,即那些,反斜杠加上对应字母,表示对应的特殊含义的,比如最常见的”\n”表示换行,”\t”表示Tab等。而如果是以r开头,那么说明后面的字符,都是普通的字符了,即如果是“\n”那么表示一个反斜杠字符,一个字母n,而不是表示换行了。
以r开头的字符,常用于正则表达式,对应着re模块。

b:bytes
python3.x里默认的str是(py2.x里的)unicode, bytes是(py2.x)的str, b”“前缀代表的就是bytes
python2.x里, b前缀没什么具体意义, 只是为了兼容python3.x的这种写法

一、字符与编码的关系

在学习之前,我们学习几个概念,让我们达成一个共识。理论上,从一个字符到具体的编码,会经过以下几个概念。
字符集(Abstract character repertoire)
编码字符集(Coded character set)
字符编码方式(Character encoding form)
字符编码方案(Character encoding scheme )

字符集:也就是我们肉眼能识别的文字,如中文、英语、德语。

编码字符集:是一个从整数集子集到字符集抽象元素的映射,即给抽象的字符编上数字。
如 Unicode 中的定义的字符,每个字符都有个数字和它对应,一只对应着一个字符。
反过来,则不一定是。这里所说的映射关系,是数学意义上的映射关系。
编码字符集也是与计算机无关的,ASCII、UTF、Unicode、GBK等字符集也在这一层。
如汉字“中文”的Unicode的编码是:\u4e2d\u6587;utf-8编码为 b'\xe4\xb8\xad\xe5\x9b\xbd',GBK的编码为:b'\xd6\xd0\xb9\xfa'

字符编码方式:这个开始与计算机有关了,编码字符集的编码点在计算机里的具体表现形式。
通俗的说,意思就是怎么样才能将字符所对应的整数的放进计算机内存、或文件、或网络中。
于是,不同人有不同的实现方式,所谓的万码奔腾,就是指这个;GB2312、UTF-8、UTF-16、UTF-32等都在这一层。
如汉字“中文”的Unicode编码为“\u4e2d\u6587”,他在计算机的存储按十六进制展开为:‭‭100 1110 0010 1101 0110 0101 1000 0111‬;

编码方案:这个更加与计算机密切相关,具体是与操作系统密切相关,主要是解决大小字节序的问题。
对于UTF-16和UTF-32编码,Unicode都支持big-endian 和 little-endian两种编码方案。


一般来说,我们所说的编码、解码,都在第二、三层完成,而序列化、反序列化在第一层。

二、编码与解码

为了简化理解,在Python3当中,只有两种编码,Unicode与 bytes,而Unicode=str,他们的转换关系:

str-->str.encode('字符编码') -->bytes -->bytes.decode('字符编码') --> str
 
 

编码(encode)就是将字符串(str)转换成字节码(bytes);
解码(decode)就是将字节码(bytes)转换为字符串(str);

举个栗子:


 
 
  1. oath = '中文'
  2. utf8 = oath.encode( 'utf-8')
  3. oath1 = utf8.decode( 'utf-8')
  4. print( "对‘中文’按utf-8进行编码:",utf8, ',长度:',len(utf8), '类型:',type(utf8), '占用字节:',sys.getsizeof(utf8))
  5. print( '对编码过的变量进行解码:',oath1, '长度:',len(oath1), '类型:',type(oath1), '占用字节:',sys.getsizeof(oath1))

运行结果:


 
 
  1. 对‘中文’按utf -8进行编码: b '\xe4\xb8\xad\xe6\x96\x87' ,长度: 6 类型: < class 'bytes'> 占用字节: 39
  2. 对编码过的变量进行解码: 中文 长度: 2 类型: < class 'str'> 占用字节: 78

证明str==Unicode


 
 
  1. oath = '我爱妞'
  2. print(oath, ',长度:',len(oath), '类型:',type(oath), '占用字节:',sys.getsizeof(oath))
  3. oath1 = u'我爱妞'
  4. print(oath1, ',长度:',len(oath1), '类型:',type(oath1), '占用字节:',sys.getsizeof(oath1))
  5. print( 'oath==oath1:',oath==oath1, '所以,str实际存储的是Unicode字符,那么也可以Unicode编码来存储str')

 
 
  1. 我爱妞 ,长度: 3 类型: < class 'str'> 占用字节: 80
  2. 我爱妞 ,长度: 3 类型: < class 'str'> 占用字节: 80
  3. oath==oath1: True 所以,str实际存储的是 Unicode字符,那么也可以 Unicode编码来存储str

另:


 
 
  1. oath2= '\u5220\u9664'
  2. print( r'所以说这样形式的Unicode字符:\u5220\u9664,可以直接显示出正确的编码:',oath2,type(oath2))
  3. print( '也可以编码为二进制字符:',oath2.encode(),type(oath2.encode()), '所以,字符串常量,前缀带不带u,都是一样的')
  4. print( r'再解码b\xe5\x88\xa0\xe9\x99\xa4,为:',oath2.encode().decode( 'utf-8'),type(oath2.encode().decode( 'utf-8')))

 
 
  1. 所以说这样形式的Unicode字符:\u5220\u9664,可以直接显示出正确的编码: 删除 < class 'str'>
  2. 也可以编码为二进制字符: b '\xe5\x88\xa0\xe9\x99\xa4' < class 'bytes'> 所以,字符串常量,前缀带不带u,都是一样的
  3. 再解码b\xe5\x88\xa0\xe9\x99\xa4,为: 删除 < class 'str'>

接下来我们来看一个例子(运行环境:Python3):

b'\xc0\xeb\xc0\xeb\xd4\xad\xc9\xcf\xb2\xdd\xa3\xac\xd2\xbb\xcb\xea\xd2\xbb\xbf\xdd\xc8\xd9'

上面这一串二进制字符是我们从某个文件读取到的字符串,我们需要知道它是什么意思,怎么办呢?

这就需要我们对他进行解码(decode)了,在解码之前我们需要知道他是什么类型的编码,才能用对应的方式进行解码,当然,你也可以一个一个的去试,但这不太程序员。


 
 
  1. import chardet
  2. data = b'\xc0\xeb\xc0\xeb\xd4\xad\xc9\xcf\xb2\xdd\xa3\xac\xd2\xbb\xcb\xea\xd2\xbb\xbf\xdd\xc8\xd9'
  3. print(type( 'data'), '检测这串bytes字符是什么编码:',chardet.detect(data))
  4. #结果:<class 'str'> 这串bytes字符是什么编码: {'encoding': 'GB2312', 'confidence': 0.7407407407407407, 'language': 'Chinese'}
  5. print( '然后可以根据检测出来的编码进行解码:',data.decode( 'GB2312'))
  6. print( '这也就解释了用什么方式编码,就要用什么方式解码')
  7. #print('当然你也可以试试用utf-8解码,你就会发现他报错:',data.decode('utf-8'))

运行结果:


 
 
  1. < class 'str'> 检测这串bytes字符是什么编码: {'encoding': 'GB2312', 'confidence': 0.7407407407407407, 'language': 'Chinese'}
  2. 然后可以根据检测出来的编码进行解码: 离离原上草,一岁一枯荣
  3. 这也就解释了用什么方式编码,就要用什么方式解码

参考原文:

https://blog.csdn.net/qq_38607035/article/details/82591931

python编码转换 以及转换成unicode报错的问题
https://www.cnblogs.com/reyinever/p/7931811.html
 
 python 查看当前字符串的编码格式
https://blog.csdn.net/sinat_24648637/article/details/84190482

https://www.zhihu.com/question/31833164

Python2 与 Python3 的编码对比
http://kuanghy.github.io/2016/10/15/encoding-python2-vs-python3

python3 三种字符串(无前缀,前缀u,前缀b)与encode()
https://blog.csdn.net/anlian523/article/details/80504699

廖雪峰的官网 字符串和编码
https://www.liaoxuefeng.com/wiki/1016959663602400/1017075323632896
 

  •                     <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                            <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#csdnc-thumbsup"></use>
                        </svg><span class="name">点赞</span>
                        <span class="count"></span>
                        </a></li>
                        <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                            <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-csdnc-Collection-G"></use>
                        </svg><span class="name">收藏</span></a></li>
                        <li class="tool-item tool-active is-share"><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;1582594662_002&quot;}"><svg class="icon" aria-hidden="true">
                            <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-csdnc-fenxiang"></use>
                        </svg>分享</a></li>
                        <!--打赏开始-->
                                                <!--打赏结束-->
                                                <li class="tool-item tool-more">
                            <a>
                            <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                            </a>
                            <ul class="more-box">
                                <li class="item"><a class="article-report">文章举报</a></li>
                            </ul>
                        </li>
                                            </ul>
                </div>
                            </div>
            <div class="person-messagebox">
                <div class="left-message"><a href="https://blog.csdn.net/u011072936">
                    <img src="https://profile.csdnimg.cn/F/9/5/3_u011072936" class="avatar_pic" username="u011072936">
                                            <img src="https://g.csdnimg.cn/static/user-reg-year/1x/7.png" class="user-years">
                                    </a></div>
                <div class="middle-message">
                                        <div class="title"><span class="tit"><a href="https://blog.csdn.net/u011072936" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">与yan有染</a></span>
                                            </div>
                    <div class="text"><span>发布了10 篇原创文章</span> · <span>获赞 3</span> · <span>访问量 2万+</span></div>
                </div>
                                <div class="right-message">
                                            <a href="https://im.csdn.net/im/main.html?userName=u011072936" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                        </a>
                                                            <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                    </div>
                            </div>
                    </div>
    </article>
    
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值