Passando valori in Python [duplicare]
-
22-08-2019 - |
Domanda
Questa domanda ha già una risposta qui:
Quando si passa una collezione come lista, un array a un'altra funzione in python, vuol fare una copia di esso, o è solo un puntatore?
Soluzione
passa riferimenti a oggetti per valore .
Python passa riferimenti a oggetti valore (come Java), e tutto il resto Python è un oggetto. Questo suona semplice, ma poi si noterà che alcuni tipi di dati sembrano mostrare pass-by-value caratteristiche, mentre altri sembrano agire come pass-by-di riferimento ... Qual è il problema?
E 'importante capire mutabili e oggetti immutabili. Alcuni oggetti, come stringhe, tuple e numeri, sono immutabile. alterarli all'interno di una la funzione / metodo creerà un nuovo istanza e l'istanza originale all'esterno della funzione / metodo non è cambiato. Altri oggetti, come le liste e dizionari sono mutabili, che significa che è possibile modificare l'oggetto a posto. Pertanto, alterare un oggetto all'interno di una funzione / metodo sarà cambiarne anche l'oggetto originale al di fuori.
Altri suggerimenti
La cosa è, l'intero concetto di riferimento / valore non rientra in pitone. Python non ha alcun "valore" di una variabile. Python ha solo gli oggetti e nomi che si riferiscono ad oggetti.
Quindi, quando si chiama una funzione e mettere un "nome" all'interno delle parentesi, in questo modo:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
L'oggetto reale che myname
sta puntando è passato, non il nome myname
si . All'interno della funzione altro nome (x
) è data per riferirsi allo stesso oggetto passato.
È possibile modificare l'oggetto all'interno della funzione se è mutevole, ma si non può cambiare ciò che il nome esterno che punta a . Proprio lo stesso che si verifica quando si fa
anothername = myname
Per questo posso rispondere alla tua domanda con:
si tratta di "passaggio per valore", ma tutti i valori sono solo riferimenti agli oggetti.
Le risposte qui sono stati utili, ma trovo la necessità di esporre questa sottile distinzione che io non ho visto coperta, che ho dimostrato a me stesso con la conseguente esperimento CL:
- Un oggetto immutabile da solo non può essere modificato all'interno di una chiamata di funzione. (risposte finora hanno detto più di tanto ...)
- MA, un oggetto immutabile contenuta all'interno di un oggetto mutabile può essere ri-assegnato all'interno di una chiamata di metodo.
'num' non cambia qui perché è un oggetto Number immutabile [supporta il mio punto 1.]:
def incr_num(num):
num += 1
num = 0
num
0
incr_num(num)
num
0
'elenco [0]' qui è un oggetto Numero immutabile anche.
def incr_list(list):
list[0] += 1
list = [0]
list[0]
0
incr_list(list)
list[0]
1
Quindi, come ha fatto 'elenco [0]', essendo un oggetto Numero immutabile, il cambiamento (supporta il mio punto 2.), mentre del esempio precedente Numero oggetto 'num' no? L'oggetto numero immutabili 'elenco [0]' è contenuto all'interno dell'oggetto lista mutabile 'lista', mentre 'num' dal 1 ° esempio è solo un oggetto non contianed numero.
Anche se buone intenzioni, mi sento @Stephen Pape risposta top-rated (citato in basso), e un po ' altri simili, non erano del tutto corrette (e che mi ha motivato a scrivere questa risposta):
Alcuni oggetti, come le stringhe, tuple e numeri, sono immutabili. alterarli all'interno di una funzione / metodo creerà una nuova istanza e l'istanza originale all'esterno della funzione / metodo non viene modificata.
Il mio esperimento secondo il codice qui sopra mostra un oggetto Number ( 'elenco [0]') in fase di modifica all'interno di un metodo, e quindi l'istanza originale di fuori della funzione modificata.
viene passato un riferimento, ma se il parametro è un oggetto immutabile, modificandolo nel metodo creerà una nuova istanza.
L'oggetto viene passato. Non una copia, ma un riferimento all'oggetto sottostante.
Vorrei anche raccomando guardando il modulo copy
:
documentazione Python per la copia
Vi aiuterà a comprendere le questioni di base e come utilizzarlo per eseguire la propria copia profonda.
Con riferimento:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
Per favore fatemi fare un esempio umile
def swap(a, b):
x = a
print id(x)
print id(a)
print id(b)
a = b
print id(a)
b = x
print id(b)
a[0]= '20'
var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)
swap(var1, var2)
print id(var1)
print id(var2)
print var1
print var2
che produce il seguente risultato
28329344 var1 28331264 var2 28329344 x 28329344 un 28331264 b Dopo a = b 28331264 un dopo b = x 28329344 b dopo il ritorno 28329344 var1 28331264 var2 [ '1', '2', '3', '4'] [ '20', '6', '7', '8', '9']
mappatura agli indirizzi di memoria 28329344 28331264 var1 var2 a b X Dopo a = b un' Dopo b = x B Dopo una [0] = '20' [0] = '20' dopo il ritorno [ '1', '2', '3', '4'] [ '20', '6', '7', '8', '9']