Pasar valores en Python [duplicar]
-
22-08-2019 - |
Pregunta
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo puedo pasar una variable por referencia? 26 respuestas
Cuando se pasa una colección como la lista, matriz a otra función en Python, ¿tiene una copia de la misma, o es sólo un puntero?
Solución
Python pasa referencias a objetos por valor .
Python pasa referencias a objetos por valor (como Java), y todo lo demás Python es un objeto. esto suena sencillo, pero entonces se dará cuenta de que algunos tipos de datos parecen mostrar pasar por valor características, mientras otros parecen actuar como el paso por referencia ... ¿cuál es el problema?
Es importante entender mutable y objetos inmutables. Algunos objetos, como cuerdas, tuplas y números, son inmutable. La alteración de ellos dentro de un la función / método creará un nuevo instancia y la instancia original fuera de la función / método no es cambiado. Otros objetos, como las listas y los diccionarios son mutables, que significa que puede cambiar el objeto en su lugar. Por lo tanto, es posible alterar una objeto dentro de una función / método se también cambiar el objeto original exterior.
Otros consejos
La cosa es que todo el concepto de referencia / valor no se ajusta a pitón. Python no tiene "valor" de una variable. Python tiene sólo objetos y nombres que se refieren a objetos.
Así que cuando se llama a una función y poner un "nombre" dentro del paréntesis, así:
def func(x): # defines a function that takes an argument
... # do something here
func(myname) # calling the function
El objeto real que se myname
se pasa Indicar, no en el nombre myname
sí . Dentro de la función otro nombre (x
) se da para referirse a la misma objeto pasado.
Puede modificar el objeto dentro de la función si es mutable, pero no puede cambiar lo que el nombre fuera está apuntando a . De la misma manera que sucede cuando lo hace
anothername = myname
Por lo tanto puedo responder a su pregunta con:
es "paso por valor", pero todos los valores son sólo referencias a objetos.
Las respuestas aquí han sido de gran ayuda, pero me parece que la necesidad de exhibir esta sutil distinción que no he visto cubierto, que he demostrado a mí mismo con el experimento posterior CL:
- Un objeto inmutable sí sola no puede ser cambiado dentro de una llamada a la función. (respuestas hasta el momento han dicho que gran parte ...)
- PERO, un objeto inmutable contenido dentro de un objeto mutable se puede volver a asignar dentro de una llamada al método.
'num' no cambia aquí porque es un objeto inmutable Número [apoya mi punto 1.]:
def incr_num(num):
num += 1
num = 0
num
0
incr_num(num)
num
0
'lista [0]' aquí es un objeto Número inmutable también.
def incr_list(list):
list[0] += 1
list = [0]
list[0]
0
incr_list(list)
list[0]
1
Entonces, ¿cómo hizo 'lista [0]', siendo un objeto Número inmutable, el cambio (es compatible con mi punto 2.) mientras que el ejemplo anterior objeto Number 'num' no lo hizo? El objeto Number inmutable 'lista [0]' está contenida dentro de la lista de objetos mutable 'lista', mientras que 'num' desde el primero ejemplo es sólo un objeto no contianed Número.
Aunque bien intencionada, siento @Stephen Pape respuesta mejor calificados (citado más abajo), y algunos otros similares, no eran totalmente correctas (y que me motivaron a escribir esta respuesta):
Algunos objetos, como cuerdas, tuplas, y los números, son inmutables. La alteración de ellos dentro de una función / método creará una nueva instancia y la instancia original fuera de la función / método no se cambia.
Mi segundo experimento código de arriba muestra un objeto Number ( 'lista [0]') siendo alterado dentro de un método, y a continuación, la instancia original fuera de la función cambió.
A de referencia se pasa, pero si el parámetro es un objeto inmutable, modificándolo dentro del método va a crear una nueva instancia.
El objeto se pasa. No es una copia, sino una referencia al objeto subyacente.
También me recomiendo mirar el módulo copy
:
documentación de Python para la copia
Esto le ayudará a entender los problemas de fondo y la forma de utilizarlo para realizar su propia copia en profundidad.
Por referencia:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
Por favor, te voy a dar un ejemplo humilde
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
que produce el resultado siguiente
28329344 var1 28331264 var2 28329344 x 28329344 una 28331264 b Después de a = b 28331264 una después de b = x 28329344 b después del regreso 28329344 var1 28331264 var2 [ '1', '2' '3', '4'] [ '20', '6', '7', '8', '9']
Asignación de las direcciones de memoria 28329344 28331264 var1 var2 a b X Después de a = b una Después de b = x si Después de un [0] = '20' [0] = '20' Tras el regreso [ '1', '2' '3', '4'] [ '20', '6', '7', '8', '9']