欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python编码与解码

程序员文章站 2024-01-16 10:39:10
...

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>
    
    相关标签: python知识