python3 中的 bytes 和 bytearray 以及他们之间的差别

python3 中的 bytes 和 bytearray 以及他们之间的差别

本文结果是:

​ bytes 是不可变的 bytearray 是可变的,就类似 元组 和 列表的关系。

如果读者只是为了寻找答案,那么。读完这句话就可以离开本页面了。

bytes

创建方式:

  1. 英文字符串前边加上 b
  2. 使用数字的数组创建 PS: bytes 本质上就是 数字 “数组”
In [1]: b = b'A bytes'

In [2]: b
Out[2]: b'A bytes'

In [12]: b[0]   # 获取第一个字符
Out[12]: 65     # 正常字符串的应该会返回大写字母 A, bytes类型实质就是数字“数组”

In [3]: b1 = bytes([97,])

In [4]: b1
Out[4]: b'a'

In [5]: a = b'中国'
  File "<ipython-input-10-a9b23923829f>", line 1
    a = b'中国'
       ^
SyntaxError: bytes can only contain ASCII literal characters.
    
In [6]: b1 = bytes([997,])
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-11-7b47f7dc2cae> in <module>
----> 1 b1 = bytes([997,])

ValueError: bytes must be in range(0, 256)

上面代码故意触发了两个错误:

​ 一个是中文字符错误, 另一个是 bytes 每个元素必须在 0-256 之内的数字。

官方解释:

​ Only ASCII characters are permitted in bytes literals (regardless of the declared source code encoding).

Any binary values over 127 must be entered into bytes literals using the appropriate escape sequence.

意思是:只有ASCII字符允许使用字节文本(不管声明的源代码编码如何)。

任何超过127的二进制值都必须使用适当的转义序列输入为字节文本。

(机器翻译)

一个中文字符要占两/三个字节文本所以不能够被直接转换。

这样操作:

In [14]: bytes([255,])
Out[14]: b'\xff'

In [15]: a  = '中国'  # 创建一个字符串

In [16]: type(a)
Out[16]: str

In [17]: a.encode('utf-8')   # 经过编码之后就是bytes了. 另外 编码也可以自己指定其他的GBK/GB2312 ... 都可以。
Out[17]: b'\xe4\xb8\xad\xe5\x9b\xbd'

说到用函数/方法操作了(我们上面用的encode),还有其他的:

# 1.
>>> bytes.fromhex('2Ef0 F1f2  ')  # 官方文档中的
b'.\xf0\xf1\xf2'
>>> b'\xf0\xf1\xf2'.hex()
'f0f1f2'
# 2. int.to_bytes(length, byteorder, *, signed=False)
>>> (1024).to_bytes(2, byteorder='big')
b'\x04\x00'
>>> x = 1000
>>> x.to_bytes((x.bit_length() + 7) // 8, byteorder='little')
b'\xe8\x03'
# 这里又要用到了字节大端与小端的一部分小知识了。。。
bytearray

bytearray 没有特定的标识符,不像 bytes 可以直接通过 b’bytes’ 创建一个bytes。

使用 bytearray() 可以创建:

In [1]: ba = bytearray(b'bytearray')

In [2]: ba
Out[2]: bytearray(b'bytearray')
    
In [3]: ba = bytearray([65,66])

In [4]: ba
Out[4]: bytearray(b'AB')

其他的:

bytearray支持所有的bytes的所有方法,可以看官方文档,都是上下重叠写的。

In [2]: b = bytes([65,66])

In [3]: ba = bytearray([65,66])

In [4]: ba
Out[4]: bytearray(b'AB')

In [5]: ba.replace(65, 68)  # 或者b.replace()...
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-11a5b185b335> in <module>
----> 1 ba.replace(65, 68)

TypeError: a bytes-like object is required, not 'int'

In [6]: ba.replace(b'A', b'C')  # 这也是我前边 说数字 "数组" 加了引号的原因。
Out[6]: bytearray(b'CB')
    
In [12]: b.replace(b'A', b'C')
Out[12]: b'CB'

In [13]: b
Out[13]: b'AB'

以上操作都是相同的 上面的ba 都能换成 b, 但是要注意一点,replace方法总是创建一个新对象。原来的对象还在。(实质上bytearray可以使用更加优雅的方式raplace掉一些字符并且不,下边的差别中我们会说到。)

那么两者有什么差别呢?

In [1]: b = bytes([65, 66]) # 相当于 b'AB'

In [2]: b
Out[2]: b'AB'

In [3]: ba = bytearray(b)

In [4]: ba
Out[4]: bytearray(b'AB')

In [5]: ba[0]
Out[5]: 65

In [6]: b[0]
Out[6]: 65

In [7]: ba[0] = 67 # 我们把 65 换成 67 表现出来也就是‘b'A' 换成了 b'C'

In [8]: ba
Out[8]: bytearray(b'CB')

In [9]: # 看我们直接在 ba 上操作替换掉了字符

In [10]: b[0] = 67
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-9b10cef766da> in <module>
----> 1 b[0] = 67

TypeError: 'bytes' object does not support item assignment

In [12]: # 报错了,这也就是两者的差异,同样也是bytearray存在的意义。。。

In [13]: # 'bytes' object does not support item assignment 不支持数据项分配(即元素修改)

总结一下:bytes 是不可变的 bytearray 是可变的,就类似 元组 和 列表的关系。

再来一个参考:https://www.cnblogs.com/dingtianwei/p/9459575.html

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值