memoryview的用法

本来第一次看《流畅的python》觉得这部分没用,就跳过去,后面又出现,回头看还是一知半解,查了诸多资料,好像有一点明白了,立下帖子。

1、memoryview

memoryview() 函数返回给定参数的内存查看对象(memory view)。

所谓内存查看对象,是指对支持缓冲区协议的数据进行包装,在不需要复制对象基础上允许Python代码访问。

可以简单理解为就是对内存地址的直接访问。

memoryview可以对对象进行索引或者切片,不过切片的返回结果为一个子memoryview对象:

import array
# 创建一个signed short 类型数组,占2bytes
nums = array.array('h', list(range(-2, 3)))
mem = memoryview(nums)
print(len(mem))  # 5
print(mem[0])    # -2
print(mem[1:4])  # <memory at 0x000002B56F01E4C8>

mem相当于nums在内存中的表示形式,但是属于不同的对象:

>>>mem is nums
False
>>>mem == nums
True

同样,memoryview对象有tolist方法可以转换为列表:

>>>mem.tolist()
[-2, -1, 0, 1, 2]

2、memoryview.cast

memoryview.cast会把同一块内存里的内容打包成一个全新的memoryview对象。

>>>mem_oct = mem.cast('B')
>>>mem.nbytes == mem_oct.nbytes
True
>>>mem.itemsize == mem_oct.itemsize
False

在转换以后,所占字节数保持不变,但是单个元素的所占字节由原来的2个变成1个(‘h’ --> ‘B’)。

Type codeC TypePython TypeMinimum size in bytes
‘c’charcharacter1
‘b’signed charint1
‘B’unsigned charint1
‘u’Py_UNICODEUnicode character2 (see note)
‘h’signed shortint2
‘H’unsigned shortint2
‘i’signed intint2
‘I’unsigned intlong2
‘l’signed longint4
‘L’unsigned longlong4
‘f’floatfloat4
‘d’doublefloat8

将mem_oct转换为list,你会发现mem_oct居然包含10个元素:

>>>mem_oct.tolist()
[254, 255, 255, 255, 0, 0, 1, 0, 2, 0]

所包含的元素也很奇怪,这个就涉及到存储的一些知识,为了将将符号位和数值域统一处理,同时加法和减法也可以统一处理,计算机系统中数值一律用补码来表示和存储。

以-2为例,初始设置其数据类型为占用两个字节的’long’,其原码是1000 0000 0000 0010,而在计算机存储的是1111 1111 1111 1110,其低八位为254,高8位为255,所以知道mem_oct前两个元素从哪里来了吧。

对于2来说,原码为0000 0000 0000 0010,补码为其本身(正数的补码与原码一致),所以转换后为2,0。

欢迎关注我的微信公众号
扫码关注公众号

### 回答1: 非常抱歉,我的上一个回答中写错了方法名,正确的方法名应该是`tobytes()`,而不是`toBytes()`。因此,正确的代码应该是: ```python def deal_one_pic(self, image): # 将图像转换为QPixmap格式 height, width, channel = image.shape bytesPerLine = 3 * width qImg = QImage(image.data.tobytes(), width, height, bytesPerLine, QImage.Format_RGB888).rgbSwapped() pixmap = QPixmap(qImg) return pixmap ``` 在上述代码中,我们使用`image.data.tobytes()`将`memoryview`类型的图像数据转换为`bytes`类型,然后将其传递给`QImage`函数。 ### 回答2: "memoryview"对象没有属性"toBytes"。这个错误通常发生在尝试将一个"memoryview"对象转换为字节对象时。 "memoryview"是Python中的一个内置对象,用于访问和操作二进制数据。它允许通过索引和切片来直接访问二进制数据,而无需复制整个数据。然而,"memoryview"对象不具有名为"toBytes"的属性。 要将"memoryview"对象转换为字节对象,可以使用内置的"bytes"函数。例如,可以使用以下代码将"memoryview"对象转换为字节对象: ```python mv = memoryview(b'Hello') bytes_obj = bytes(mv) ``` 在这个例子中,我们先创建了一个"memoryview"对象"mv",它引用了一个包含字符串"Hello"的字节数组。然后,我们使用"bytes"函数将"memoryview"对象转换为字节对象"bytes_obj"。 需要注意的是,转换为字节对象时会创建一个新的字节对象,而不是改变原始的"memoryview"对象。因此,在转换之后,"memoryview"对象仍然没有"toBytes"属性。 总结起来,"memoryview"对象没有"toBytes"属性,如果想将其转换为字节对象,可以使用内置的"bytes"函数。 ### 回答3: 在回答这个问题之前,首先需要了解一下'memoryview'对象和'toBytes'属性的含义。 'memoryview'是一个内置对象,它用于访问和操作二进制数据。它提供了一种查看数据的方式,而不需要复制整个数据。通过'memoryview'对象,我们可以直接对数据进行切片、索引和修改。这对于处理大型数据集非常有用。 'toBytes'属性是一个常见的属性,它通常用于将数据转换成字节格式。这个属性可能是由用户自定义的,也可能是来自某个库或模块。 根据所提供的错误信息,'memoryview'对象没有'toBytes'属性,这意味着我们无法直接将'memoryview'对象转换为字节格式的数据。 要将'memoryview'对象转换为字节格式,我们可以使用内置的'bytes()'函数。该函数接受一个可迭代的对象并返回一个字节字符串。我们可以将'memoryview'对象作为参数传递给'bytes()'函数,以便将其转换为字节格式。以下是一个示例代码: ```python # 创建一个包含整数的内存视图对象 data = memoryview([65, 66, 67, 68]) # 将内存视图对象转换为字节格式 bytes_data = bytes(data) # 打印字节格式的数据 print(bytes_data) ``` 上述代码首先创建了一个内存视图对象,其中包含了一些整数。然后,我们通过将内存视图对象传递给'bytes()'函数,将其转换为字节格式。最后,通过打印输出,我们可以看到转换后的字节数据。 总而言之,当出现'memoryview'对象没有'toBytes'属性的错误时,我们可以使用内置的'bytes()'函数将其转换为字节格式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值