Python:将数组定义为实例类属性

时间:2015-04-22 05:49:29

标签: arrays class python-3.x attributes overwrite

我需要有几个对象,每个对象都有一个单独的数组。我写了这段代码:

    read_values = list()
    for read_unit in read_units:
        read_value = ReadValues.objects.all().filter(ReadID=read_unit.ReadID)

        element = TempObjectForReadValues()
        for read_element in read_value:
            element.read_elements[read_element.Code] = read_element.ReadValue
        read_values.append(element)
        print(element.read_elements)

    print('  ')
    for test_element in read_values:
        print(test_element.read_elements)

这就是我定义课程的方式:

    class TempObjectForReadValues():
        read_elements = [None] * 10

结果是:

[None, None, 16.0, None, 189.0, 345.0, None, None, None, None]
[None, None, 16.0, 43.0, 876.0, 345.0, None, None, None, None]

[None, None, 16.0, 43.0, 876.0, 345.0, None, None, None, None]
[None, None, 16.0, 43.0, 876.0, 345.0, None, None, None, None]

这意味着数据会被以前的数据覆盖。此外,如果我没有在新对象中为数组指定任何内容,它将保留前一个数据的结果。 :(

我该如何解决?

1 个答案:

答案 0 :(得分:1)

与Java和C ++不同,Python语法不指定类主体上的实例属性。相反,类主体中指定的任何属性都是 属性。 这意味着您的read_elements数组实际上是在TempObjectForReadValues类的所有实例中共享的单例。

要解决这个问题,只需在对象的初始化代码中创建作为实例属性的任何属性(即__init__方法):

class TempObjectForReadValues:
    def __init__(self):
        self.read_elements = [None] * 10

现在,请注意,对于更复杂的类层次结构和特定需求,Python确实实现了一种名为" descriptor protocol"允许指定为类属性的专用对象管理每个实例上具有相同名称的属性的读/写和删除。

最常见的用途之一是property(它甚至是语言中的内置函数) - 它只需要1到3个可调用参数,每个参数都是一个getter / setter / deleter一个属性。这种机制也可以用于ORM策略,接口实现和许多其他事情。

在你的情况下,你可以这样做:

class TempObjectForReadValues:
    read_elements = property(lambda self: self.__dict__.setdefault("_read_elements", [None] * 10))

(这是一个将代码保持在一行中的hackish实现,相当于:

class TempObjectForReadValues:
    @property
    def read_elements(self):
        if not hasattr(self, "_read_elements"):
            self._read_elements = [None] * 10
        return self._read_elements