developing - python reference 3
AsignaciĆ³n de referencia variable de Python (4)
En el código
y = 7
x = y
x = 8
Ahora, y será 7 yx será 8. Pero en realidad quiero cambiar y. ¿Puedo asignar la referencia de y y hacer eso?
Por ejemplo, en C ++ se puede lograr lo mismo que,
int y = 8;
int &x = y;
x = 9;
Ahora tanto yyx serán 9
Alternativamente, puede usar un contenedor auto elaborado.
class Value(object):
def __init__(self, value): self.value = value
y = Value(7)
x = y
x.value = 8
print y.value
Deberías usar un objeto mutable para esto.
En Python x
& y
son solo referencias a objetos, por lo que y = 7
significa que y apunta al objeto 7
. x=y
significa que x
también apunta a 7
, pero como 7
es inmutable, cambiar el valor de x simplemente cambia el objeto 7
e y
aún permanece apuntando a 7
.
>>> y = [7]
>>> x = y
>>> x[0] = 8 # here you''re changing [7] not x or y, x & y are just references to [7]
>>> y
[8]
No, no puedes. Como señala otra respuesta, puede (¿ab?) Usar aliasing de objetos mutables para lograr un efecto similar. Sin embargo, eso no es lo mismo que las referencias de C ++, y quiero explicar lo que realmente sucede para evitar cualquier concepto erróneo.
Verá, en C ++ (y en otros idiomas), una variable (y campos de objetos, y entradas en colecciones, etc.) es una ubicación de almacenamiento y usted escribe un valor (por ejemplo, un entero, un objeto o un puntero) para esa ubicación En este modelo, las referencias son un alias para una ubicación de almacenamiento (de cualquier tipo): cuando asigna una variable que no es de referencia, copia un valor (incluso si solo es un puntero, sigue siendo un valor) en la ubicación de almacenamiento; cuando asigna a una referencia, copia en un lugar de almacenamiento en otro lugar. Tenga en cuenta que no puede cambiar una referencia en sí misma; una vez que está enlazada (y tiene que hacerlo tan pronto como la cree), todas las asignaciones a la misma alteran no la referencia, sino lo que sea que se haga referencia a ella.
En Python (y en otros idiomas), una variable (y campos de objetos, y entradas en colecciones, etc.) es solo un nombre. Los valores están en otro lugar (p. Ej., Salpicado todo el montón) y una variable se refiere (no en el sentido de referencias de C ++, más como un puntero menos la aritmética del puntero) a un valor. Varios nombres pueden referirse al mismo valor (que generalmente es algo bueno). Python (y otros idiomas) llama a lo que sea necesario para referirse a un valor de referencia, a pesar de no estar relacionado con cosas como referencias de C ++ y referencias pasadas. Asignar a una variable (o campo de objeto, o ...) simplemente lo hace referirse a otro valor. El modelo completo de ubicaciones de almacenamiento no se aplica a Python, el programador nunca maneja ubicaciones de almacenamiento para valores. Todo lo que almacena y baraja son referencias de Python, y esos no son valores en Python, por lo que no pueden ser el objetivo de otras referencias de Python.
Todo esto es independiente de la mutabilidad del valor; es lo mismo para los Ints y las listas, por ejemplo. No puede tomar una variable que haga referencia a ninguno de los dos y sobrescribir el objeto al que apunta. Solo puede decirle al objeto que modifique partes de sí mismo, por ejemplo, cambie alguna referencia que contenga.
¿Es este un modelo más restrictivo? Tal vez, pero es lo suficientemente potente la mayor parte del tiempo. Y cuando no lo es, puede evitarlo, ya sea con una clase personalizada como la que se muestra a continuación, o (equivalente, pero menos obvio) una colección de elementos individuales.
class Reference:
def __init__(self, val):
self._value = val # just refers to val, no copy
def get(self):
return self._value
def set(self, val):
self._value = val
Eso todavía no le permitirá alias una variable "normal" o un campo de objeto, pero puede tener múltiples variables que hagan referencia al mismo objeto de Reference
(ídem para la alternativa mutable-singleton-collection). Solo debes tener cuidado de usar siempre .get()
/ .set()
(o [0]
).