¿Por qué asignarse a uno mismo no funciona y cómo solucionar el problema?

Tengo una clase (lista de dict ) y quiero que se clasifique por sí misma:

 class Table(list): … def sort (self, in_col_name): self = Table(sorted(self, key=lambda x: x[in_col_name])) 

pero no funciona en absoluto. ¿Por qué? ¿Cómo evitarlo? Excepto por su clasificación externa, como:

 new_table = Table(sorted(old_table, key=lambda x: x['col_name']) 

¿No es posible manipular el objeto en sí? Es más significativo tener:

 class Table(list): pass 

que:

 class Table(object): l = [] … def sort (self, in_col_name): self.l = sorted(self.l, key=lambda x: x[in_col_name]) 

Lo cual, creo, funciona. Y en general, ¿no hay alguna forma en Python en la que un objeto pueda cambiarse a sí mismo (no solo una variable de instancia)?

No puede reasignarse a self desde un método y esperar que cambie las referencias externas al objeto.

self es solo un argumento que se pasa a tu función. Es un nombre que apunta a la instancia en la que se invocó el método. “Asignarse a self ” es equivalente a:

 def fn(a): a = 2 a = 1 fn(a) # a is still equal to 1 

La asignación a self cambia a lo que apunta el nombre (desde una instancia de Table a una nueva instancia de Table aquí). Pero eso es todo. Simplemente cambia el nombre (en el scope de su método) y no afecta al objeto subyacente, ni a otros nombres (referencias) que lo señalan.


Solo list.sort en su lugar usando list.sort :

 def sort(self, in_col_name): super(Table, self).sort(key=lambda x: x[in_col_name]) 

Python es pasar por valor, siempre. Esto significa que la asignación a un parámetro nunca tendrá un efecto en el exterior de la función. self es solo el nombre que eligió para uno de los parámetros.

Me intrigó esta pregunta porque nunca había pensado en esto. Busqué el código de list.sort para ver cómo se hace allí, pero aparentemente está en C. Creo que veo a donde te diriges; ¿Y si no hay un método super para invocar? Entonces puedes hacer algo como esto:

 class Table(list): def pop_n(self, n): for _ in range(n): self.pop() >>> a = Table(range(10)) >>> a.pop_n(3) >>> print a [0, 1, 2, 3, 4, 5, 6] 

Puede llamar a los métodos del self , hacer asignaciones de índice a self y cualquier otra cosa que se implemente en su clase (o que usted mismo ).