• Python二进制序列类型(一)bytes与bytearray


    Python实用教程_spiritx的博客-CSDN博客

    Python中有一类特殊的对象称为字节类对象,可在多种二进制数据操作中使用,如图片、音频、视频数据,通过socket套接字发送数据,以及与C语言的API进行数据交互等等。

    bytes 只负责以字节序列的形式(二进制形式)来存储数据,至于这些数据到底表示什么内容(字符串、数字、图片、音频等),完全由程序的解析方式决定。如果采用合适的字符编码方式(字符集),字节串可以恢复成字符串;反之亦然,字符串也可以转换成字节串。

    说的更直白一点,bytes 只是简单地记录内存中的原始数据,至于如何使用这些数据,bytes 并不在意,你想怎么使用就怎么使用,bytes 并不约束你的行为。

    包括所有 bytes、bytearray 和 array.array 对象,以及许多普通 memoryview 对象。

    bytes

    bytes 对象是由单个字节构成的不可变序列。

    Bytes 本质是一串由 0 和 1 组成的二进制串,但为了显示方便,每八位划分为一组,然后按组显示。如果这八位正好是一个可打印的 ASCII 字符的编码,如 A、z、0、% 等,则显示该字符;如果不是,则显示十六进制。

    由于许多主要二进制协议都基于 ASCII 文本编码,因此 bytes 对象提供了一些仅在处理 ASCII 兼容数据时可用,并且在许多特性上与字符串对象紧密相关的方法。

    字节串(bytes)和字符串(string)的对比:

    • 字符串由若干个字符组成,以字符为单位进行操作;字节串由若干个字节组成,以字节为单位进行操作。
    • 字节串和字符串除了操作的数据单元不同之外,它们支持的所有方法都基本相同。
    • 字节串和字符串都是不可变序列,不能随意增加和删除数据。

    字符串和 bytes 存在着千丝万缕的联系,我们可以通过字符串来创建 bytes 对象,或者说将字符串转换成 bytes 对象。有以下三种方法可以达到这个目的:

    • 如果字符串的内容都是 ASCII 字符,那么直接在字符串前面添加b前缀就可以转换成 bytes。
    • bytes 是一个类,调用它的构造方法,也就是 bytes(),可以将字符串按照指定的字符集转换成 bytes;如果不指定字符集,那么默认采用 UTF-8。
    • 字符串本身有一个 encode() 方法,该方法专门用来将字符串按照指定的字符集转换成对应的字节串;如果不指定字符集,那么默认采用 UTF-8。

    创建bytes

    创建bytes有多种方法,一种是通过bytes进行显示的声明和转换,一种是从其他对象生成或转换而来。

    声明和定义bytes对象

    语法:

    class bytes([source[, encoding[, errors]]])

    通过bytes()函数显示声明一个bytes类型

    首先,表示 bytes 字面值的语法与字符串字面值的大致相同,只是添加了一个 b 前缀:

    • 单引号: b'同样允许嵌入 "双" 引号'
    • 双引号: b"仍然允许嵌入 '单' 引号"
    • 三重引号: b'''三重单引号'''b"""三重双引号"""

    bytes 字面值中只允许 ASCII 字符(无论源代码声明的编码为何)。 任何超出 127 的二进制值必须使用相应的转义序列形式加入 bytes 字面值。

    像字符串字面值一样,bytes 字面值也可以使用 r 前缀来禁用转义序列处理。

    虽然 bytes 字面值和表示法是基于 ASCII 文本的,但 bytes 对象的行为实际上更像是不可变的整数序列,序列中的每个值的大小被限制为 0 <= x < 256 (如果违反此限制将引发 ValueError)。 这种限制是有意设计用以强调以下事实,虽然许多二进制格式都包含基于 ASCII 的元素,可以通过某些面向文本的算法进行有用的操作,但情况对于任意二进制数据来说通常却并非如此(盲目地将文本处理算法应用于不兼容 ASCII 的二进制数据格式往往将导致数据损坏)。

    除了字面值形式,bytes 对象还可以通过其他几种方式来创建:

    • 指定长度的以零值填充的 bytes 对象: bytes(10)
    • 通过由整数组成的可迭代对象: bytes(range(20))
    • 通过缓冲区协议复制现有的二进制数据: bytes(obj)
    1. >>> b'123'
    2. b'123'
    3. >>> b'一二三'
    4. File "", line 1
    5. b'一二三'
    6. ^
    7. SyntaxError: bytes can only contain ASCII literal characters
    8. #大于 127 的字符建议使用 \xhh 表示。
    9. >>> b'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89'
    10. b'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89’
    11. >>> bytes('一二三', 'utf-8')
    12. b'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89’
    13. >>> '一二三'.encode() # 或 '一二三'.encode('utf-8')
    14. b'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89’
    15. >>> s = '这是一个中文字符串'
    16. >>> b = s.encode('utf-8')
    17. >>> print(b)
    18. b'\xe8\xbf\x99\xe6\x98\xaf\xe4\xb8\x80\xe4\xb8\xaa\xe4\xb8\xad\xe6\x96\x87\xe5\xad\x97\xe7\xac\xa6\xe4\xb8\xb2'

    从十六进制字符串转换

    语法:

    classmethod bytes.fromhex(string)

    通过bytes的类方法将一个包含16进制数字串的string转换为bytes类型

    由于两个十六进制数码精确对应一个字节,因此十六进制数是描述二进制数据的常用格式。 相应地,bytes 类型具有从此种格式读取数据的附加类方法。

    方法返回一个解码给定字符串的 bytes 对象。 字符串必须由表示每个字节的两个十六进制数码构成,其中的 ASCII 空白符会被忽略。

    1. >>>bytes.fromhex('2Ef0 F1f2 ')
    2. b'.\xf0\xf1\xf2'

    从一般字符串转换

    语法:

    str.encode(encoding='UTF-8',errors='strict')

    参数:

    • encoding -- 要使用的编码,如"UTF-8"。
    • errors -- 设置不同错误的处理方案。默认为 'strict',意为编码错误引起一个UnicodeError。 其他可能得值有 'ignore', 'replace', 'xmlcharrefreplace', 'backslashreplace' 以及通过 codecs.register_error() 注册的任何值。

    返回编码后的字节串

    如:

    1. >>> str = "C语言中文网"
    2. >>> str.encode()
    3. b'C\xe8\xaf\xad\xe8\xa8\x80\xe4\xb8\xad\xe6\x96\x87\xe7\xbd\x91'

    转换为其他类型

    转换为十六进制字符串

    语法格式:

    hex([sep[, bytes_per_sep]])

    可以将 bytes 对象转换为对应的十六进制表示.

    返回一个字符串对象,该对象包含实例中每个字节的两个十六进制数字。

    1. >>>b'\xf0\xf1\xf2'.hex()
    2. ‘f0f1f2'
    3. #将字符转化为 GBK 编码:
    4. #方法一:
    5. >>> bytes('一二三', 'gbk').hex()
    6. 'd2bbb6fec8fd'
    7. #方法二:
    8. >>> '一二三'.encode('gbk').hex()
    9. ‘d2bbb6fec8fd'
    10. #将 GBK 编码转化为字符 :
    11. #方法一:
    12. >>> str(bytes.fromhex('d2bbb6fec8fd'), 'gbk')
    13. '一二三'
    14. #方法二:
    15. >>> bytes.fromhex('d2bbb6fec8fd').decode('gbk')
    16. '一二三'

    如果你希望令十六进制数字符串更易读,你可以指定单个字符分隔符作为 sep 形参包含于输出中。 默认情况下,该分隔符会放在每个字节之间。 第二个可选的 bytes_per_sep 形参控制间距。 正值会从右开始计算分隔符的位置,负值则是从左开始。

    1. >>>value = b'\xf0\xf1\xf2'
    2. >>>value.hex('-')
    3. 'f0-f1-f2'
    4. >>>value.hex('_', 2)
    5. 'f0_f1f2'
    6. >>>b'UUDDLRLRAB'.hex(' ', -4)
    7. '55554444 4c524c52 4142'

    由于 bytes 对象是由整数构成的序列(类似于元组),因此对于一个 bytes 对象 bb[0] 将为一个整数,而 b[0:1] 将为一个长度为 1 的 bytes 对象。 (这与文本字符串不同,索引和切片所产生的将都是一个长度为 1 的字符串)。

    bytes 对象的表示使用字面值格式 (b'...'),因为它通常都要比像 bytes([46, 46, 46]) 这样的格式更好用。 你总是可以使用 list(b) 将 bytes 对象转换为一个由整数构成的列表。

    转换为一般字符串 

    语法格式:

    bytes.decode(encoding='utf-8'errors='strict')

    encoding为编码格式

    返回解码为 str 的字节串。

    errors 控制如何处理编码错误。

    含意

    'strict'

    引发 UnicodeError (或其子类),这是默认的方案。 在 strict_errors() 中实现。

    'ignore'

    忽略错误格式的数据并且不加进一步通知就继续执行。 在 ignore_errors() 中实现。

    'replace'

    用一个替代标记来替换。 在编码时,使用 ? (ASCII 字符)。 在解码时,使用 � (U+FFFD,官方的 REPLACEMENT CHARACTER)。 在 replace_errors() 中实现。

    'backslashreplace'

    用反斜杠转义序列来替换。 在编码时,使用格式为 \xhh \uxxxx \Uxxxxxxxx 的 Unicode 码位十六进制表示形式。 在解码时,使用格式为 \xhh 的字节值十六进制表示形式。 在 backslashreplace_errors() 中实现。

    'surrogateescape'

    在解码时,将字节替换为 U+DC80 至 U+DCFF 范围内的单个代理代码。 当在编码数据时使用 'surrogateescape' 错误处理方案时,此代理将被转换回相同的字节。 

    1. >>> str(b'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89', 'utf-8')
    2. '一二三'
    3. >>> b'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89'.decode()
    4. '一二三'

    其他方法

    查找和匹配方法

    统计子串出现的次数

    语法为:

    bytes.count(sub[, start[, end]])

    返回子序列 sub 在 [startend] 范围内非重叠出现的次数。 可选参数 start 与 end 会被解读为切片表示法。

    如果 sub 为空,则返回字节串对象的长度加一.

    1. a = b'abcabcabd'
    2. print(a.count(b'')) #4
    3. print(a.count(b'ab'))#3
    匹配前缀

    语法为:

    bytes.startswith(prefix[, start[, end]])

    如果二进制数据以指定的 prefix 开头则返回 True,否则返回 False。 prefix 也可以为由多个供查找的前缀构成的元组。 如果有可选项 start,将从所指定位置开始检查。 如果有可选项 end,将在所指定位置停止比较。

    1. s = b'Apollo'
    2. print(f"{s.startswith(b'Ap')=}") #s.startswith(b'Ap')=True
    3. #s.startswith('Ap') #TypeError prefix必须是bytes类型
    4. s = b'Apollo'
    5. print(f"{s.startswith(b'po')=}") #s.startswith(b'po')=False
    6. s = b'Apollo'
    7. print(f"{s.startswith(b'Apo')=}") #s.startswith(b'Apo')=True
    8. print(f"{s.startswith(b'Apo',1,4)=}") #s.startswith(b'Apo',1,4)=False
    匹配后缀

    语法为:

    bytes.endswith(suffix[, start[, end]])

    如果二进制数据以指定的 suffix 结束则返回 True,否则返回 False。 suffix 也可以为由多个供查找的后缀构成的元组。 如果有可选项 start,将从所指定位置开始检查。 如果有可选项 end,将在所指定位置停止比较。

    删除前缀

    语法为:

    bytes.removeprefix(prefix/)

    如果二进制数据以 prefix 字符串开头,返回 bytes[len(prefix):]。 否则,返回原始二进制数据的副本:

    1. >>>b'TestHook'.removeprefix(b'Test')
    2. b'Hook'
    3. >>>b'BaseTestCase'.removeprefix(b'Test')
    4. b'BaseTestCase'

    注意:此方法的 bytearray 版本 并非 原地操作 —— 它总是产生一个新对象,即便没有做任何改变,后面的其他方法也基本是这样的,如果有特别的会进行单独说明。

    删除后缀

    语法:

    bytes.removesuffix(suffix/)

    如果二进制数据以 suffix 字符串结尾,并且 suffix 非空,返回 bytes[:-len(suffix)]。 否则,返回原始二进制数据的副本:

    1. >>> b'demo.py'.removesuffix(b'.py')
    2. b'demo'
    3. >>> b'demo.py'.removesuffix(b'.cpp')
    4. b'demo.py'
    查找子串

    语法:

    bytes.find(sub[, start[, end]])

    返回子序列 sub 在数据中被找到的最小索引,sub 包含于切片 s[start:end] 之内。 可选参数 start 与 end 会被解读为切片表示法。 如果 sub 未被找到则返回 -1

    备注 find() 方法应该只在你需要知道 sub 所在位置时使用。 要检查 sub 是否为子串,请使用 in 操作符:

    1. >>> b'py' in b'demo.py'
    2. True

    语法:

    bytes.index(sub[, start[, end]])

    类似于 find(),但在找不到子序列时会引发 ValueError。

    1. >>> x = 0x32
    2. >>> b'1234'.index(bytes([x]))
    3. 1
    从右查找子串

    语法:

    bytes.rfind(sub[, start[, end]])

    返回子序列 sub 在序列内被找到的最大(最右)索引,这样 sub 将包含在 s[start:end] 当中。 可选参数 start 与 end 会被解读为切片表示法。 如果未找到则返回 -1

    语法:

    bytes.rindex(sub[, start[, end]])

    类似于 rfind(),但在子序列 sub 未找到时会引发 ValueError。

    拆分字节串

    拆分为三元组

    语法:

    bytes.partition(sep)

    在 sep 首次出现的位置拆分序列,返回一个 3 元组,其中包含分隔符之前的部分、分隔符本身或其 bytearray 副本,以及分隔符之后的部分。 如果分隔符未找到,则返回的 3 元组中包含原序列以及两个空的 bytes 或 bytearray 对象。

    语法:

    bytes.rpartition(sep)

    在 sep 最后一次出现的位置拆分序列,返回一个 3 元组,其中包含分隔符之前的部分,分隔符本身或其 bytearray 副本,以及分隔符之后的部分。 如果分隔符未找到,则返回的 3 元组中包含两个空的 bytes 或 bytearray 对象以及原序列的副本。

    1. >>> b'demo.py'.rpartition(b'.')
    2. (b'demo', b'.', b'py')
    3. >>> b'demo.py'.partition(b'.')
    4. (b'demo', b'.', b'py')
    5. >>> b'demo.20230904.py'.rpartition(b'.')
    6. (b'demo.20230904', b'.', b'py')
    7. >>> b'demo.20230904.py'.partition(b'.')
    8. (b'demo', b'.', b'20230904.py')

    注意与patition()方法的差别,rpatition()并没有把返回序列的三个元素的顺序倒置过来,r体现的是获取sep的位置。

    多元组拆分

    语法:

     bytes.split(sep=Nonemaxsplit=- 1)

    将二进制序列拆分为相同类型的子序列,使用 sep 作为分隔符。 如果给出了 maxsplit 且非负值,则最多进行 maxsplit 次拆分(因此,列表最多会有 maxsplit+1 个元素)。 如果 maxsplit 未指定或为 -1,则不限制拆分次数(进行所有可能的拆分)。

    如果给出了 sep,则连续的分隔符不会被组合在一起而是被视为分隔空子序列 (例如 b'1,,2'.split(b',') 将返回 [b'1', b'', b'2'])。 sep 参数可能为一个多字节序列 (例如 b'1<>2<>3'.split(b'<>') 将返回 [b'1', b'2', b'3'])。 使用指定的分隔符拆分空序列将返回 [b''] 或 [bytearray(b'')],具体取决于被拆分对象的类型。

    1. >>>b'1,2,3'.split(b',')
    2. [b'1', b'2', b'3']
    3. >>>b'1,2,3'.split(b',', maxsplit=1)
    4. [b'1', b'2,3']
    5. >>>b'1,2,,3,'.split(b',')
    6. [b'1', b'2', b'', b'3', b'']

    如果 sep 未指定或为 None,则会应用另一种拆分算法:连续的 ASCII 空白符会被视为单个分隔符,其结果将不包含序列开头或末尾的空白符。 因此,在不指定分隔符的情况下对空序列或仅包含 ASCII 空白符的序列进行拆分将返回 []

    1. >>>b'1 2 3'.split()
    2. [b'1', b'2', b'3']
    3. >>>b'1 2 3'.split(maxsplit=1)
    4. [b'1', b'2 3']
    5. >>>b' 1 2 3 '.split()
    6. [b'1', b'2', b'3']

    语法:

     bytes.rsplit(sep=Nonemaxsplit=- 1)

    将二进制序列拆分为相同类型的子序列,使用 sep 作为分隔符。 如果给出了 maxsplit,则最多进行 maxsplit 次拆分,从 最右边 开始。 如果 sep 未指定或为 None,任何只包含 ASCII 空白符的子序列都会被作为分隔符。 除了从右边开始拆分,rsplit() 的其他行为都类似于下文所述的 split()。

    按行拆分

     bytes.splitlines(keepends=False)

    返回由原二进制序列中各行组成的列表,在 ASCII 行边界符的位置拆分。结果列表中不包含换行符,除非给出了 keepends 且为真值。

    Unix 的行结束约定 '\n'、Windows 的约定 '\r\n' 以及旧版 Macintosh 的约定 '\r'

    不同于 split(),当给出了分隔符 sep 时,对于空字符串此方法将返回一个空列表,而末尾的换行不会令结果中增加额外的行:

    1. >>>b"".split(b'\n'), b"Two lines\n".split(b'\n')
    2. ([b''], [b'Two lines', b''])
    3. b"".splitlines(), b"One line\n".splitlines()
    4. ([], [b'One line'])

    对齐

    左对齐

    语法:

    bytes.ljust(width[, fillbyte])

    返回原对象的副本,在长度为 width 的序列中靠左对齐。 使用指定的 fillbyte 填充空位(默认使用 ASCII 空格符)。 对于 bytes 对象,如果 width 小于等于 len(s) 则返回原序列的副本。

    右对齐

    语法:

    bytes.rjust(width[, fillbyte])

    返回原对象的副本,在长度为 width 的序列中靠右对齐。 使用指定的 fillbyte 填充空位(默认使用 ASCII 空格符)。 对于 bytes 对象,如果 width 小于等于 len(s) 则返回原序列的副本。

    此方法的 bytearray 版本 并非 原地操作 —— 它总是产生一个新对象,即便没有做任何改变。

    居中

    语法: 

    bytes.center(width[, fillbyte])

    返回原对象的副本,在长度为 width 的序列内居中,使用指定的 fillbyte 填充两边的空位(默认使用 ASCII 空格符)。对于 bytes 对象,如果 width 小于等于 len(s) 则返回原序列的副本。

     去空格

    去前(左)空格

    语法:

    bytes.lstrip([chars])

    返回原序列的副本,移除指定的前导字节。 chars 参数为指定要移除字节值集合的二进制序列 —— 这个名称表明此方法通常是用于 ASCII 字符。 如果省略或为 None,则 chars 参数默认移除 ASCII 空白符。 chars 参数并非指定单个前缀;而是会移除参数值的所有组合:

    1. >>> b' www'.lstrip()
    2. b'www'
    3. >>> b'abc-abc-abcd'.lstrip(b'abcd')
    4. b'-abc-abcd'
    去后(右)空格

    语法:

    bytes.rstrip([chars])

    返回原序列的副本,移除指定的末尾字节。 chars 参数为指定要移除字节值集合的二进制序列 —— 这个名称表明此方法通常是用于 ASCII 字符。 如果省略或为 None,则 chars 参数默认移除 ASCII 空白符。 chars 参数并非指定单个后缀;而是会移除参数值的所有组合:

    去前后空格

    bytes.strip([chars])

    返回原序列的副本,移除指定的开头和末尾字节。 chars 参数为指定要移除字节值集合的二进制序列 —— 这个名称表明此方法通常是用于 ASCII 字符。 如果省略或为 None,则 chars 参数默认移除 ASCII 空白符。 chars 参数并非指定单个前缀或后缀;而是会移除参数值的所有组合:

    1. >>>b' spacious '.strip()
    2. b'spacious'
    3. >>>b'www.example.com'.strip(b'cmowz.')
    4. b'example'

    字符类型判断

    字母数字串

    bytes.isalnum()

    如果序列中所有字节都是字母类 ASCII 字符或 ASCII 十进制数码并且序列非空则返回 True ,否则返回 False 。 字母类 ASCII 字符就是字节值包含在序列 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的字符。 ASCII 十进制数码就是字节值包含在序列 b'0123456789' 中的字符。

    1. >>>b'ABCabc1'.isalnum()
    2. True
    3. >>>b'ABC abc1'.isalnum()
    4. False
    字母串

    bytes.isalpha()

    如果序列中所有字节都是字母类 ASCII 字符并且序列不非空则返回 True ,否则返回 False 。 字母类 ASCII 字符就是字节值包含在序列 b'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 中的字符。

    1. >>>b'ABCabc'.isalpha()
    2. True
    3. >>>b'ABCabc1'.isalpha()
    4. False
    ASCII串

    bytes.isascii()

    如果序列为空或序列中所有字节都是 ASCII 字节则返回 True ,否则返回 False 。 ASCII 字节的取值范围是 0-0x7F。

    数字串

    bytes.isdigit()

    如果序列中所有字节都是 ASCII 十进制数码并且序列非空则返回 True ,否则返回 False 。 ASCII 十进制数码就是字节值包含在序列 b'0123456789' 中的字符。

    小写串

    bytes.islower()

    如果序列中至少有一个小写的 ASCII 字符并且没有大写的 ASCII 字符则返回 True ,否则返回 False 。

    大写串

    bytes.isupper()

    如果序列中至少有一个大写字母 ASCII 字符并且没有小写 ASCII 字符则返回 True ,否则返回 False 。

    空格串

    bytes.isspace()

    如果序列中所有字节都是 ASCII 空白符并且序列非空则返回 True ,否则返回 False 。 ASCII 空白符就是字节值包含在序列 b' \t\n\r\x0b\f' (空格, 制表, 换行, 回车, 垂直制表, 进纸) 中的字符。

    标题串

    bytes.istitle()

    如果序列为 ASCII 标题大小写形式并且序列非空则返回 True ,否则返回 False 。

    其中每个单词以一个大写 ASCII 字符为开头,其余字母为小写。 不区别大小写的字节值将保持原样不变。

    替换和转换

    转为小写

     bytes.lower()

    返回原序列的副本,其所有大写 ASCII 字符均转换为对应的小写形式。

    转为大写

    bytes.upper()

    返回原序列的副本,其所有小写 ASCII 字符均转换为对应的大写形式。

    大小写互换

    bytes.swapcase()

    返回原序列的副本,其所有小写 ASCII 字符均转换为对应的大写形式,反之亦反。

    1. >>>b'Hello World'.swapcase()
    2. b'hELLO wORLD'
    替换

    bytes.replace(oldnew[, count])

    返回序列的副本,其中出现的所有子序列 old 都将被替换为 new。 如果给出了可选参数 count,则只替换前 count 次出现。

    注意:此方法的 bytearray 版本 并非 原地操作 —— 它总是产生一个新对象,即便没有做任何改变。

    首字母大写

    bytes.capitalize()

    返回原序列的副本,其中每个字节将都将被解读为一个 ASCII 字符,并且第一个字节的字符大写而其余的小写。 非 ASCII 字节值将保持原样不变。

    制表符替换为空格

     bytes.expandtabs(tabsize=8)

    返回序列的副本,其中所有的 ASCII 制表符会由一个或多个 ASCII 空格替换,具体取决于当前列位置和给定的制表符宽度。 每 tabsize 个字节设为一个制表位(默认值 8 时设定的制表位在列 0, 8, 16 依次类推)。 要展开序列,当前列位置将被设为零并逐一检查序列中的每个字节。 如果字节为 ASCII 制表符 (b'\t'),则并在结果中插入一个或多个空格符,直到当前列等于下一个制表位。 (制表符本身不会被复制。) 如果当前字节为 ASCII 换行符 (b'\n') 或回车符 (b'\r'),它会被复制并将当前列重设为零。 任何其他字节会被不加修改地复制并将当前列加一,不论该字节值在被打印时会如何显示:

    1. >>>b'01\t012\t0123\t01234'.expandtabs()
    2. b'01 012 0123 01234'
    3. >>>b'01\t012\t0123\t01234'.expandtabs(4)
    4. b'01 012 0123 01234'

    按码表转换

    static bytes.maketrans(fromto)

    此静态方法返回一个可用于 bytes.translate() 的转换对照表,它将把 from 中的每个字符映射为 to 中相同位置上的字符;from 与 to 必须都是 字节类对象 并且具有相同的长度。

    bytes.translate(table/delete=b'')

    返回原 bytes 或 bytearray 对象的副本,移除其中所有在可选参数 delete 中出现的 bytes,其余 bytes 将通过给定的转换表进行映射,该转换表必须是长度为 256 的 bytes 对象。

    你可以使用 bytes.maketrans() 方法来创建转换表。

    1. >>>b'read this short text'.translate(None, b'aeiou')
    2. b'rd ths shrt txt'

    转换为标题串

    bytes.title()

    返回原二进制序列的标题版本,其中每个单词以一个大写 ASCII 字符为开头,其余字母为小写。 不区别大小写的字节值将保持原样不变。

    该算法使用一种简单的与语言无关的定义,将连续的字母组合视为单词。 该定义在多数情况下都很有效,但它也意味着代表缩写形式与所有格的撇号也会成为单词边界,这可能导致不希望的结果:

    1. >>>b"they're bill's friends from the UK".title()
    2. b"They'Re Bill'S Friends From The Uk"

    可以使用正则表达式来构建针对撇号的特别处理:

    1. >>>import re
    2. >>>def titlecase(s):
    3. return re.sub(rb"[A-Za-z]+('[A-Za-z]+)?",
    4. lambda mo: mo.group(0)[0:1].upper() +
    5. mo.group(0)[1:].lower(),
    6. s)
    7. >>>titlecase(b"they're bill's friends.")
    8. b"They're Bill's Friends."

    填充

    bytes.zfill(width)

    返回原序列的副本,在左边填充 b'0' 数码使序列长度为 width。 正负值前缀 (b'+'/ b'-') 的处理方式是在正负符号 之后 填充而非在之前。 对于 bytes 对象,如果 width 小于等于 len(seq) 则返回原序列。

    连接

    bytes.join(iterable)

    返回一个由 iterable 中的二进制数据序列拼接而成的 bytes 或 bytearray 对象。 如果 iterable 中存在任何非 字节类对象 包括存在 str 对象值则会引发 TypeError。 提供该方法的 bytes 或 bytearray 对象的内容将作为元素之间的分隔。

    bytearray

    bytearray 对象是 bytes 对象的可变对应物。

    class bytearray([source[, encoding[, errors]]])

    bytearray 对象没有专属的字面值语法,它们总是通过调用构造器来创建:

    • 创建一个空实例: bytearray()
    • 创建一个指定长度的以零值填充的实例: bytearray(10)
    • 通过由整数组成的可迭代对象: bytearray(range(20))
    • 通过缓冲区协议复制现有的二进制数据: bytearray(b'Hi!')

    由于 bytearray 对象是可变的,该对象除了 bytes 中所描述的 共有操作之外,还支持 可变 序列操作。

    可选形参 source 可以用不同的方式来初始化数组:

    • 如果是一个 string,您必须提供 encoding 参数(errors 参数仍是可选的);bytearray() 会使用 str.encode() 方法来将 string 转变成 bytes。
    • 如果是一个 integer,会初始化大小为该数字的数组,并使用 null 字节填充。
    • 如果是一个遵循 缓冲区接口 的对象,该对象的只读缓冲区将被用来初始化字节数组。
    • 如果是一个 iterable 可迭代对象,它的元素的范围必须是 0 <= x < 256 的整数,它会被用作数组的初始内容。
    • 如果没有实参,则创建大小为 0 的数组。

    bytes的方法,bytearray都支持,用法也一致。

    1. >>> a = bytearray(3) # 创建一个长度为 3, 元素值为 0 的 bytearray
    2. >>> a
    3. bytearray(b'\x00\x00\x00')
    4. >>> a[0] = 97; a[1] = 255 # 修改数字元素的值
    5. >>> a
    6. bytearray(b'a\xff\x00')
    7. >>> a.append(65) # 追加一个元素到末尾
    8. >>> a
    9. bytearray(b'a\xff\x00A')
    10. >>>
    11. >>> a = bytearray("abc你好", "utf-8") # 编码字符串创建 bytearray
    12. >>> a
    13. bytearray(b'abc\xe4\xbd\xa0\xe5\xa5\xbd')
    14. >>>
    15. >>> a = bytearray([1, 2, 3, 65, 97]) # 把整数列表中的各元素串起来转换为 bytearray
    16. >>> a
    17. bytearray(b'\x01\x02\x03Aa')
    18. >>>
    19. >>> a = bytearray(b"abc123") # 根据 bytes 序列创建 bytearray
    20. >>> a
    21. bytearray(b'abc123')

    bytearray独有的方法:

    追加一个元素

    bytearray.append(item: int)

    添加一个元素到末尾, 值为 [0, 255] 区间内的整数

    1. # 创建一个二进制串,并赋值
    2. b = bytearray([0x44, 0x4C, 0x4a, 0x26])
    3. print(b) # 输出对应ASCII字符串:bytearray(b'DLJ&')
    4. # 添加一个元素
    5. b.append(0x3A)
    6. print(b) # 输出对应ASCII字符串:bytearray(b'DLJ&:')
    7. # 创建一个8字节空间,赋空值
    8. b = bytearray(8)
    9. print(len(b)) # 输出 --> 8
    10. # 给b设置值
    11. b[0] = 0x44
    12. b[1] = 0x4d
    13. print(b) # bytearray(b'DM\x00\x00\x00\x00\x00\x00')
    14. # 以字符串创建一个二进制
    15. b = bytearray(b'abc')
    16. # 修改字符串值
    17. b[1] = ord('R')
    18. print(b) # bytearray(b'aRc')
    19. # 通过16进制字符串构建二进制
    20. b = bytearray.fromhex('444c')
    21. print(b) # bytearray(b'DL')
    22. # 二进制字符串转换为int,一个int为4字节,需要通过struct模块转换
    23. import struct
    24. b = bytearray([0x01, 0x02, 0x03, 0x04])
    25. print(struct.unpack('i', b)) # 输出(67305985,)

    参入一个元素

    bytearray.insert(index: int, item: int)

    在 index 位置插入一个元素, 值为 [0, 255] 区间内的整数

    追加可迭代对象

    bytearray.extend(iterable)

    把可迭代对象的所有元素依次添加到数组的末尾,迭代元素的值必须为 [0, 255] 区间内的整数

    移除一个元素

    bytearray.remove(item: int)

    移除一个元素, 从左到右查找

    弹出最后一个元素

    bytearray.pop(index: int = -1)

    移除并返回指定位置元素, 默认是最后一个

    1. my_array = bytearray([1, 2, 3, 4, 5])
    2. my_array.append(6)
    3. my_array.extend([7, 8, 9])
    4. my_array.insert(0, 0)
    5. my_array.pop(3)
    6. my_array.remove(4)
    7. my_array.reverse()
    8. print(my_array)
    9. bytearray(b'[9, 8, 7, 6, 5, 3, 2, 1, 0')

    字节串反转

    bytearray.reverse()

    反转所有数组元素

    1. # 字节对象
    2. b = bytes([1, 2, 3, 4, 5])
    3. # 反向迭代器
    4. reversed_b = reversed(b)
    5. # 反向字节序列
    6. reversed_bytes = bytes(reversed_b)
    7. print(reversed_bytes)
    8. #b'\x05\x04\x03\x02\x01'

    拷贝副本

    bytearray.copy()

    复制数组的内容, 创建其副本返回

    清除元素

    bytearray.clear()

    清空数组内的所有元素

  • 相关阅读:
    Hexagon_V65_Programmers_Reference_Manual(8)
    基于PHP+html的学生课外活动成果统计系统
    算法通关村第12关【白银】| 字符串经典问题
    云服务器ip使用细节(公网、私有)
    域控操作三点五:使用策略下发将域用户添加到本地管理员组
    软考-软件工程
    linux软件安装
    linux c base64编码解码
    【隐私计算】SIRNN: A Math Library for Secure RNN Inference
    N皇后问题(分支限界法)
  • 原文地址:https://blog.csdn.net/spiritx/article/details/132677303