如何在python中实现类似数组的属性包装器?

时间:2013-06-03 08:53:41

标签: python wrapper ctypes

我在python中有一个类作为c-library的前端。该库执行模拟并处理非常大的数据数组。该库传递ctype数组,我的包装器将其转换为适当的numpy.ndarray

class SomeClass(object):
    @property
    def arr(self):
        return numpy.array(self._lib.get_arr())

但是,为了确保不会出现内存问题,我将ndarray数据与库数据分开,因此更改ndarray不会导致库使用的真实数组发生更改。但是,我可以传递一个相同形状的新数组并覆盖库的保持数组。

@arr.setter
def arr(self, new_arr):
    self._lib.set_arr(new_arr.ctypes)

所以,我可以这样与数组交互:

x = SomeClass()
a = x.arr
a[0] += 1
x.arr = a

我希望通过简单地将语法简化为x.arr[0] += 1来简化这一过程,这将更易读并且变量更少。我不确定如何创建这样一个包装器(我很少有制作包装器类/函数的经验)模仿属性但允许项目访问作为我的例子。

我将如何制作这样的包装类?有没有更好的方法来实现这一目标?如果您有任何建议或阅读可以帮助我非常感激。

2 个答案:

答案 0 :(得分:3)

这可行。 Array是Numpy / C数组的代理:

class Array(object):

    def __init__(self):
        #self.__lib = ...
        self.np_array = numpy.array(self._lib.get_arr())

    def __getitem__(self, key): 
        self.np_array = numpy.array(self._lib.get_arr())
        return self.np_array.__getitem__(key)

    def __setitem__(self, key, value):
        self.np_array.__setitem__(key, value)
        self._lib.set_arr(new_arr.ctypes)

    def __getattr__(self, name):
        """Delegate to NumPy array."""
        try:
            return getattr(self.np_array, name)
        except AttributeError:
            raise AttributeError(
                 "'Array' object has no attribute {}".format(name))

应该是这样的:

>>> a = Array()
>>> a[1]
1
>>> a[1] = 10
>>> a[1]
10

10也应该在你的C数组中结束。

答案 1 :(得分:0)

我认为您的描述符应该返回类似于列表的类的实例,该类知道self._lib并在正常操作append__setitem____getitem__等期间更新它。