es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , ,

Answer

  1. Avatar for 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:

    class A():
        def __init__(self, N, M):
            self.large_matrix = np.zeros((N, M))
            self.some_set = [0, 1, 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
    
        def set_value(self, index, value):
            self.large_matrix[index, self.some_set] = value
    

    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 en large_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:

    my_object.set_value(2, 5)
    

    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 modificar self.some_set antes de llamar a set_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 setter matrix se encargará de actualizar el atributo large_matrix.

Comments are closed.