Cómo utilizar la indexación con el decorador @property
Estoy tratando de cambiar ciertos índices de un atributo de clase que es una matriz con decoradores de Python. El problema es que no sé cómo especificar el índice con el método setter. Mi código es algo como esto:
class A():
def __init__(self, N, M):
self.large_matrix = np.zeros(N, M)
self.some_set = [1,2,3]
@property
def matrix(self):
return self.large_matrix[:,self.some_set]
@matrix.setter
def matrix(self,value):
self.large_matrix[:,self.some_set] = value
Con esta clase quiero cambiar ciertos valores de la matriz grande accediendo a la matriz más pequeña, por ejemplo:
self.matrix[index] = value
Sin embargo, esto no funciona. El código se ejecuta sin errores, pero los valores en la matriz grande no cambian.
En cambio, si escribo:
self.matrix = value
Funciona perfectamente. También debo mencionar que es crucial tener los decoradores, ya que el atributo self.some_set
cambia a veces. Por lo tanto, quiero que la matriz grande permanezca intacta en aquellos índices en los que no estoy trabajando, pero necesito almacenarlos en la clase para referencias posteriores.
Una solución que encontré es la siguiente:
m = self.matrix.copy()
m[index] = value
self.matrix = m
Esto funciona, pero supongo que el código se vuelve mucho más lento (lo cual es un factor) y es laborioso cambiar esto en todas partes del código. Para aclarar; la matriz necesita ser accedida dentro de la clase. ¿Existe alguna solución para modificar el decorador y el método @matrix.setter
para que el código siga siendo eficiente y no tenga que cambiar el código en todas partes?
davy.ai
Una posible solución a este problema es crear un nuevo método setter específicamente para cambiar valores en ciertos índices de la matriz. Aquí tienes un ejemplo:
En esta clase modificada, hemos añadido un nuevo método
set_value
que toma un índice y un valor como argumentos, y cambia el valor correspondiente enlarge_matrix
. Este método puede ser llamado desde dentro de la clase, por lo que no tienes que cambiar el código en todos lados.Por ejemplo, si quieres cambiar el valor en el índice 2, puedes llamar a:
Esto cambiará el valor en el índice 2 de las columnas especificadas en
self.some_set
a 5. Si quieres cambiar un conjunto diferente de columnas, puedes modificarself.some_set
antes de llamar aset_value
.Ten en cuenta que aún puedes usar la propiedad
matrix
para obtener y establecer la matriz completa o un subconjunto de ella, como antes. El nuevo método settermatrix
se encargará de actualizar el atributolarge_matrix
.