如何为非连续的内存位置创建内存视图?

时间:2013-12-13 11:23:54

标签: python memory memoryview

我在内存中有一个碎片结构,我想将它作为一个连续的内存视图来访问它。有没有一种简单的方法可以做到这一点,还是应该实现我自己的解决方案?

例如,考虑一个由记录组成的文件格式。每条记录都有一个固定长度的标题,用于指定记录内容的长度。更高级别的逻辑结构可能分布在多个记录中。如果它可以将自己的碎片内存位置视为一个简单的连续字节数组,那么它将使更高级别的结构更容易实现。

更新

似乎python在内部支持这种“分段”缓冲区类型,至少基于this part of the documentation。但这只是C API。

UPDATE2:

据我所知,引用的C API - 称为旧式缓冲区 - 可以满足我的需求,但现在已经弃用,并且在较新版本的Python(3.X)中不可用。新的缓冲区协议 - 在PEP 3118中指定 - 提供了一种表示缓冲区的新方法。这个API在大多数用例中更有用(其中,表示缓冲区在内存中不连续的用例),但不支持这个特定的用例,其中一维数组可以完全自由地布局(多个不同)记忆中的大小。

1 个答案:

答案 0 :(得分:1)

首先 - 我假设你只是想在纯python而不是c扩展中这样做。所以我假设您已经将您感兴趣的不同记录加载到一组python对象中,并且您的问题是您希望在整个对象中看到遍布这些对象的更高级别结构。 / p>

那么你能不能简单地将每个记录加载到字节数组类型中?然后,您可以使用python切片数组来创建一个新数组,该数组只包含您感兴趣的高级结构的数据。然后,您将拥有一个单独的字节数组,其中只包含您感兴趣的数据并可以将其打印出来或者以任何你想要的方式操纵它。

类似于:

a = bytearray(b"Hello World") # put your records into byte arrays like this
b = bytearray(b"Stack Overflow")
complexStructure = bytearray(a[0:6]+b[0:]) # Slice and join arrays to form
                                           # new array with just data from your
                                           # high level entity
print complexStructure

当然,你仍然需要知道你的高级结构在记录中的哪个位置正确地切割数组,但无论如何你都需要知道这一点。

修改

注意,获取列表的一部分不会复制列表中的数据,只会创建一组新的数据引用,所以:

>>> a = [1,2,3]
>>> b = a[1:3]
>>> id(a[1])
140268972083088
>>> id(b[0])
140268972083088

但是,对列表b的更改不会更改,因为b是新列表。要使更改在原始列表中自动更改,您需要创建一个更复杂的对象,其中包含原始记录的列表,并以这样的方式隐藏它们,以便能够决定更改列表和列表的哪个元素或查看用户何时修改/查看复杂结构。如下所示:

class ComplexStructure():
    def add_records(self,record):
        self.listofrecords.append(record)

    def get_value(self,position):
        listnum,posinlist = ... # formula to figure out which list and where in 
                                # list element of complex structure is
        return self.listofrecords[listnum][record]

    def set_value(self,position,value):
        listnum,posinlist = ... # formula to figure out which list and where in 
                                # list element of complex structure is
        self.listofrecords[listnum][record] = value

当然,这不是你希望做的事情的简单方式,但它应该做你需要的。