Нечто подобное могло бы работать, но я должен сказать, что это очень своеобразный шаблон дизайна:
class My(object):
_arrays = {}
def __init__(self, N):
self._dimension = N
self._arr(N)
def _arr(self, N):
if N not in self._arrays:
arr = [i for i in range(0,N)]
self._arrays[N] = arr
return self._arrays
@property
def a(self):
return self._arrays[self._dimension]
@a.setter
def a(self, new):
if len(new) != self._dimension:
raise ValueError('Wrong length, should be %d but was %d' %
(self._dimension, len(new)))
self._arrays[self._dimension] = new
if __name__ == '__main__':
a = My(5)
b = My(5)
c = My(10)
print "# Instances of the same size get the same array:"
print "a.a and b.a same instance: %r" % (a.a is b.a)
print "a.a and c.a same instance: %r" % (a.a is c.a)
a.a[0] = 'five'
c.a[0] = 'ten'
print "# Updating the arrays work:"
print "a array contents: %r" % a.a
print "b array contents: %r" % b.a
print "c array contents: %r" % c.a
a.a = list('abcde') # new array
print "# Changing the reference to a new array works:"
print "a array contents: %r" % a.a
print "b array contents: %r" % b.a
print "# Size is protected:"
a.a = [1, 2, 3]
В этом классе, каждый раз, когда создается экземпляр, метод _arr
называется. Он создаст и сохранит новый массив правильной длины в словаре _arrays
, который является членом класса. Правильный массив для текущего экземпляра просматривается, когда свойство a
доступно или изменено.
Вы также можете установить self.a = self._arrays[self._dimension]
, но это не сработает, если вы попытаетесь назначить новый массив, например a.a = [1, 2, 3]
, и вы также можете получить массив неправильной длины. Сетчатчик позаботится об этом.
Результат выглядит следующим образом:
# Instances of the same size get the same array:
a.a and b.a same instance: True
a.a and c.a same instance: False
# Updating the arrays work:
a array contents: ['five', 1, 2, 3, 4]
b array contents: ['five', 1, 2, 3, 4]
c array contents: ['ten', 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Changing the reference to a new array works:
a array contents: ['a', 'b', 'c', 'd', 'e']
b array contents: ['a', 'b', 'c', 'd', 'e']
# Size is protected:
Traceback (most recent call last):
File "arrays.py", line 47, in <module>
a.a = [1, 2, 3]
File "arrays.py", line 22, in a
(self._dimension, len(new)))
ValueError: Wrong length, should be 5 but was 3
Вы можете сообщить нам, что вы пытаетесь достичь? Или почему вам нужно, чтобы это была переменная класса? – Kedar
этот массив с [1,2,3, ..] был просто примером, указывающим на проблему. В действительности я бы использовал разреженные матрицы из scipy с некоторыми записями (не так просто). У меня есть идея создать два массива классов - один хранит размер уже созданных массивов, а второй - с адресом памяти, где начинается массив. Можно ли установить указатель на эту ячейку памяти, как в C++? –
Если массива нет - он его создает. Если он присутствует, он устанавливает указатель на него. –