我对Python有点新(1天),所以也许我的问题很愚蠢。我已经看了here,但我找不到答案。
我需要以随机大小随机偏移修改数组的内容。 我有一个Python API来连接USB设备的DDL,我无法修改。有一个函数就像这个:
def read_device(in_array):
# The DLL accesses the USB device, reads it into in_array of type array('B')
# in_array can be an int (the function will create an array with the int
# size and return it), or can be an array or, can be a tuple (array, int)
在我的代码中,我创建了一个数组,比方说,64字节,我想从32字节开始读取16个字节。在C中,我将&my_64_array[31]
赋予read_device
函数。
在python中,如果给出:
read_device(my_64_array[31:31+16])
似乎in_array是对给定子集的副本的引用,因此my_64_array
不会被修改。
我该怎么办?我是否必须拆分my_64_array
并在??之后重新组合
答案 0 :(得分:1)
了解您无法更新和/或更改API代码的方式。最好的方法是将函数传递给一个小的临时数组,然后在函数调用之后将其分配给现有的64字节数组。
因此,如下所示,不知道API调用的具体细节。
the_64_array[31:31+16] = read_device(16)
答案 1 :(得分:0)
在阅读列表子集时,您使用该列表的__getitem__
参数调用slice(x, y)
。在您的情况下,这些陈述是相同的:
my_64_array[31:31+16]
my_64_array.__getitem__(slice(31, 31+16))
这意味着可以在子类中重写__getitem__
函数以获得不同的行为。
您还可以使用a[1:3] = [1,2,3]
设置相同的子集,在这种情况下,它会调用a.__setitem__(slice(1, 3), [1,2,3])
所以我建议其中任何一个:
my_64_array
)和slice
对象传递给read_device,而不是传递__getitem__
的结果,之后您可以读取必要的数据并设置相应的偏移量。没有子类化。就可读性和易开发性而言,这可能是最佳解决方案。__getitem__
和__setitem__
以使用父引用返回该子类的实例,然后更改列表的所有修改或读取方法以引用父列表。如果你是python的新手,这可能有点棘手,但基本上,你会利用python列表属性主要由list
实例中的方法定义。这可能在性能方面更好,因为您可以创建引用。read_device
返回结果列表,并且该列表大小相同,则可以执行以下操作:a[x:y] = read_device(a[x:y])
答案 2 :(得分:0)
正如您所说,如果您将切片输入到函数中,它会创建切片的参考副本。
稍后添加它的两种可能方法(假设read_device
返回相关切片):
my_64_array = my_64_array[:32] + read_device(my_64_array[31:31+16]) + my_64_array[31+16:]
# equivalently, but around 33% faster for even small arrays (length 10), 3 times faster for (length 50)...
my_64_array[31:31+16] = read_device(my_64_array[31:31+16])
所以我认为你应该使用后者。
如果它是一个可修改的函数(但不是在这种情况下!)你可以改变你的函数参数(一个是整个数组):
def read_device(the_64_array, start=31, end=47):
# some code
the_64_array[start:end] = ... #modifies `in_array` in place
并致电read_device(my_64_array)
或read(my_64_array, 31, 31+16)
。