• python3 的 str bytes 区别


    在Python 3版本中,把'xxx'和u'xxx'统一成Unicode编码,即写不写前缀u都是一样的。

    在Python 3版本中,所有的字符串都是使用Unicode编码的字符串序列。

    Python 3最重要的新特性之一是对字符串和二进制数据流做了明确的区分。文本总是 Unicode,由 str 类型表示,二进制数据则由 bytes 类型表示。Python 3 不会以任意隐式的方式混用 str 和 bytes ,你不能拼接字符串和字节流,也无法在字节流里搜索字符串(反之亦然),也不能将字符串传入参数为字节流的函数(反之亦然)。

    # -*- coding: utf-8 -*-
    """
    @author: tz_zs
    """
    import sys

    # 查看默认编码

    print(sys.getdefaultencoding()) # utf-8
    
    b = b'xe4xb8xadxe5x9bxbd' # py3定义bytes使用 b = b'dfja'
    print(b, type(b)) # b'xe4xb8xadxe5x9bxbd' <class 'bytes'>
    b_decode = b.decode('utf-8')
    print(b_decode, type(b_decode)) # 中国 <class 'str'>
    
    s = '中国' # Python3中定义的字符串(str)默认就是 unicode字符串
    print(s, type(s)) # 中国 <class 'str'>
    # s1 = s.decode("utf-8") # AttributeError: 'str' object has no attribute 'decode' ← Python3中字符串不再有decode方法
    
    s2 = s.encode("gbk") # 将字符串(str)用 “gbk字符编码” 编码为 “gbk字符编码的字节”
    print(s2, type(s2)) # b'xd6xd0xb9xfa' <class 'bytes'>
    s22 = s2.decode('gbk') # 将 “字节串” 用 “gbk字符编码” 解码 为 “字符串(str)”
    print(s22, type(s22)) # 中国 <class 'str'>
    
    s3 = s.encode("utf-8")
    print(s3, type(s3)) # b'xe4xb8xadxe5x9bxbd' <class 'bytes'>
    s33 = s.encode("utf-8").decode('utf-8')
    print(s33, type(s33)) # 中国 <class 'str'>

    bytes和str之间的异同
    回到bytes和str的身上。bytes是一种比特流,它的存在形式是01010001110这种。我们无论是在写代码,还是阅读文章的过程中,肯定不会有人直接阅读这种比特流,它必须有一个编码方式,使得它变成有意义的比特流,而不是一堆晦涩难懂的01组合。因为编码方式的不同,对这个比特流的解读也会不同,对实际使用造成了很大的困扰。下面让我们看看Python是如何处理这一系列编码问题的:

    >>> s = "中文"
    >>> s
    '中文'
    >>> type(s)
    <class 'str'>
    >>> b = bytes(s, encoding='utf-8')
    >>> b
    b'xe4xb8xadxe6x96x87'
    >>> type(b)
    <class 'bytes'>

    从例子可以看出,s是个字符串类型。Python有个内置函数bytes()可以将字符串str类型转换成bytes类型,b实际上是一串01的组合,但为了在ide环境中让我们相对直观的观察,它被表现成了b'xe4xb8xadxe6x96x87'这种形式,开头的b表示这是一个bytes类型。xe4是十六进制的表示方式,它占用1个字节的长度,因此”中文“被编码成utf-8后,我们可以数得出一共用了6个字节,每个汉字占用3个,这印证了上面的论述。在使用内置函数bytes()的时候,必须明确encoding的参数,不可省略。

    我们都知道,字符串类str里有一个encode()方法,它是从字符串向比特流的编码过程。而bytes类型恰好有个decode()方法,它是从比特流向字符串解码的过程。除此之外,我们查看Python源码会发现bytes和str拥有几乎一模一样的方法列表,最大的区别就是encode和decode。

    从实质上来说,字符串在磁盘上的保存形式也是01的组合,也需要编码解码。

    如果,上面的阐述还不能让你搞清楚两者的区别,那么记住下面两几句话:

    在将字符串存入磁盘和从磁盘读取字符串的过程中,Python自动地帮你完成了编码和解码的工作,你不需要关心它的过程。

    使用bytes类型,实质上是告诉Python,不需要它帮你自动地完成编码和解码的工作,而是用户自己手动进行,并指定编码格式。

    Python已经严格区分了bytes和str两种数据类型,你不能在需要bytes类型参数的时候使用str参数,反之亦然。这点在读写磁盘文件时容易碰到。

    在bytes和str的互相转换过程中,实际就是编码解码的过程,必须显式地指定编码格式。

    >>> b
    b'xe4xb8xadxe6x96x87'
    >>> type(b)
    <class 'bytes'>
    >>> s1 = str(b)
    >>> s1
    "b'\xe4\xb8\xad\xe6\x96\x87'"
    >>> type(s1)
    <class 'str'>
    >>> s1 = str(b, encoding='utf-8')
    >>> s1
    '中文'
    >>> type(s1)
    <class 'str'>

    我们再把字符串s1,转换成gbk编码的bytes类型:

    >>> s1
    '中文'
    >>> type(s1)
    <class 'str'>
    >>> b = bytes(s1, encoding='gbk')
    >>> b
    b'xd6xd0xcexc4'
  • 相关阅读:
    贪心+stack Codeforces Beta Round #5 C. Longest Regular Bracket Sequence
    暴力/DP Codeforces Beta Round #22 (Div. 2 Only) B. Bargaining Table
    DFS Codeforces Round #299 (Div. 2) B. Tavas and SaDDas
    二分搜索 Codeforces Round #299 (Div. 2) C. Tavas and Karafs
    水题 Codeforces Round #299 (Div. 2) A. Tavas and Nafas
    数学 2015百度之星初赛2 HDOJ 5255 魔法因子
    贪心/数学 2015百度之星资格赛 1004 放盘子
    模拟 2015百度之星资格赛 1003 IP聚合
    rails安装使用版本控制器的原因。
    ActiveStorage. 英文书Learnrails5.2的案例,看如何放到云上。
  • 原文地址:https://www.cnblogs.com/lincappu/p/12465228.html
Copyright © 2020-2023  润新知