Domanda

Questo può essere per la maggior parte delle lingue in generale, ma non sono sicuro. Sono un principiante in Python e ho sempre lavorato su copie di elenchi in C # e VB. Ma in pitone ogni volta che passo una lista come parametro e enumerare utilizzando un "for i in range", e quindi modificare il valore dell'argomento lista, i valori di ingresso cambia in realtà l'elenco originale. Ho pensato Python doveva passare gli argomenti per valore di default in modo che una volta che la funzione è terminata ho ancora i valori originali da prima ho chiamato la funzione. Che cosa mi manca? Grazie!

È stato utile?

Soluzione

Python fa passare gli argomenti per valore, ma il valore che si sta ricevendo è una copia del riferimento (per inciso questo è esattamente lo stesso modo in cui C #, VB.NET e Java si comportano come bene).

Questa è la cosa importante da ricordare:

  

Gli oggetti non sono passati per riferimento -. Riferimenti a oggetti sono passati per valore

Dal momento che si dispone di una copia del riferimento, qualsiasi operazione su quello che sarà che i punti di riferimento ai proprio come se si fosse in possesso il riferimento originale in sé.

Altri suggerimenti

Python - proprio come Java fa per nulla, ma scalari primitivi, e, come C # e VB.NET fanno per i parametri di tipo predefinito al contrario di scatola tipi e fuori parms / ref - pass "con riferimento a un oggetto" (ricerca di quella frase qui - è come Guido, architetto e creatore di Python, utilizza per spiegare questo argument- passa concetto).

Ogni nome è un riferimento a qualche oggetto; passando un nome (o qualsiasi altra espressione) come argomento è solo creando un ulteriore riferimento allo stesso oggetto (quale il corpo funzione può accedere attraverso il nome del parametro). ((Non esiste una cosa come "un riferimento a un nome": ci sono i nomi di , che sono un tipo di riferimento a oggetti, e l'oggetto - periodo)).

Quando si sta passando un oggetto mutabile, vale a dire quella che ha mutando metodi (come ad esempio una lista), la funzione chiamata può mutare l'oggetto chiamando, direttamente o indirettamente, i suoi metodi mutazione. ((Per "indirettamente", intendo "attraverso gli operatori" - per esempio:

somelist[len(somelist):] = [whatever]

è esattamente identico a somelist.append(whatever).))

Quando si desidera passare un elenco in una funzione, ma fare non vuole la funzione di essere in grado di mutare l'elenco in qualsiasi modo, è necessario passare un copia della lista al posto dell'originale -. proprio come in Java, C #, VB.NET

essere molto chiara la distinzione tra rebinding un nome e mutare un oggetto . Rebinding il nome ( "barename", vale a dire - qualificata nomi sono diversi ;-) solo affetti che nome - non qualsiasi oggetto di sorta. Ad esempio:

def f1(alist):
  alist = [23]

def f2(alist):
  alist[:] = [23]

Si può individuare la differenza tra queste due funzioni? Uno è rebinding il barename alist - senza alcun effetto di sorta su qualsiasi cosa. L'altro sta mutando (alterazione, modifica, ...) l'oggetto lista ha ricevuto come argomento - impostando il suo contenuto ad essere un elenco di un elemento con un int come unico elemento. completamente, assolutamente cose diverse !!!

Per aggiungere alla risposta di Andrea, è necessario fare in modo esplicito una copia di una lista, se si desidera conservare l'originale. È possibile farlo utilizzando il modulo copy, o semplicemente fare qualcosa di simile

a = [1,2]
b = list(a)

Dato che gli oggetti copia di solito implica un calo di prestazioni, lo trovo utile utilizzare in modo esplicito il modulo copy nei miei progetti di grandi dimensioni. In questo modo, posso facilmente trovare tutti i posti in cui ho intenzione di utilizzare un gruppo più memoria.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top