Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

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?

¿Fue útil?

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 . 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:

  1. 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 ...)
  2. 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']

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top