Sovrascrivi la memoria usando le classi quando si usano gli elenchi in python

-1

Sto provando a creare una nuova variabile con la classe Lamb (chiamata hold) usando una variabile (main), che ha anche Lamb di classe. Lamb ha due parametri (xey).

Creo una variabile chiamata main con class Lamb dove main.x è una lista. Quindi creo hold usando main.x e main.y (vedi codice snip 2 sotto). Quando provo a cambiare hold.x (1) cambia anche main.x (1). Questo comportamento non è osservato quando non uso una lista in main.x e hold.x.

Come faccio a smettere di hold.x (1) cambiando main.x (1)? Una descrizione più dettagliata del mio problema e quello che ho provato è sotto.

Ho scoperto che quando voglio prendere un valore da una variabile di una certa classe non posso semplicemente assegnargli una nuova variabile (hold = var.x). Se lo faccio allora quando cambio hold python cambia anche var.x.

Per risolvere questo problema, tieni premuto avere la stessa classe di var (hold.x = var.x) come mostrato sotto

class Lamb():
def __init__(self,x,y):
    self.x = x
    self.y = y
main = Lamb([1,"a"],2)
print("main.x =",main.x,":",main)

hold = Lamb(main.x,main.y)
hold.x = "b"

print("main.x =",main.x,":",main)
print("hold.x =",hold.x,":",hold)

main.x = [1, 'a']: < main .Lamb oggetto a 0x01A26D10 >

main.x = [1, 'a']: < main .Lamb oggetto a 0x01A26D10 >

hold.x = b: < main .Lamb oggetto a 0x01B606F0 >

Notare che main.x! = hold.x.

Funziona come previsto, ma se provo a cambiare solo il valore "a" in hold.x, cambio anche il valore "a" in main.x.

class Lamb():
def __init__(self,x,y):
    self.x = x
    self.y = y

main = Lamb([1,"a"],2)
print("main.x =",main.x,":",main)

hold = Lamb(main.x,main.y)
hold.x[1] = "b"                       #[1] IS THE ONLY THING I CHANGED

print("main.x =",main.x,":",main)
print("hold.x =",hold.x,":",hold)

main.x = [1, 'a']: < main .Lamb oggetto a 0x01216D10 >

main.x = [1, 'b']: < main .Lamb oggetto a 0x01216D10 >

hold.x = [1, 'b']: < main .Lamb oggetto a 0x012606F0 >

Notate ora main.x = hold.x

Questo comportamento è strano per me a causa delle chiamate di memoria nelle istruzioni di stampa. main e hold hanno entrambi posizioni distinte nella memoria. Forse hold.x sta puntando a main.x ma quello non sembra essere quello che sta accadendo guardando l'esempio sopra.

Ho una soluzione ma preferirei non usarla. Assegnare un valore a ciascun valore nel principale quindi utilizzare questi valori invece di main.x e main.y. Preferirei non farlo. C'è un modo migliore per creare una copia di main e modificare solo un singolo valore di un parametro che è una lista?

x deve avere una lunghezza indeterminata se lo faccio in questo modo ho bisogno di avere un valore di mantenimento per ogni valore in main.x.

class Lamb():
def __init__(self,x,y):
    self.x = x
    self.y = y

main = Lamb([1,"a"],2)
print("main.x =",main.x,":",main)


holdx0 = main.x[0]
holdx1 = main.x[1]
holdy = main.y

hold = Lamb([holdx0,holdx1],holdy)
hold.x[1] = "b"


print("main.x =",main.x,":",main)
print("hold.x =",hold.x,":",hold)

main.x = [1, 'a']: < main .Lamb oggetto a 0x01BB0710 >

main.x = [1, 'a']: < main .Lamb oggetto a 0x01BB0710 >

hold.x = [1, 'b']: < main .Lamb oggetto a 0x01BB0610 >

Grazie per il tuo aiuto.

    
posta Alexander Schoen 28.09.2016 - 17:01
fonte

1 risposta

0

Dopo aver creato main e hold, entrambi sono memorizzati in posizioni diverse nella memoria, nel tuo caso: 0x01A26D10 e 0x01B606F0.

Inizialmente, le loro variabili x puntano alla stessa posizione in memoria (qualunque cosa sia), dove è memorizzata la lista [1, "a"].

Non appena assegni hold.x = 'b', quindi hold.x punta da un'altra parte rispetto a main.x

Ma, nel tuo secondo esempio in cui assegni hold.x [1]="b", stai semplicemente cambiando un elemento di una lista che è un oggetto mutabile, e quindi hold.x punta ancora allo stesso punto di main.x

Per ottenere il comportamento necessario, anziché:

hold = Lamb(main.x,main.y)

Preferirei fare una copia approfondita di main:

import copy
hold = copy.deepcopy(main)

Oppure, come suggerito da Tanner Swett, crea una copia dell'elenco:

hold = Lamb(list(main.x), main.y)
    
risposta data 29.09.2016 - 08:11
fonte

Leggi altre domande sui tag