1

Entiendo las diferencias entre paso por valor y paso por referencia, pero al investigar un poco acerca de Python encontré que no utiliza los modelos antes mencionados, sino uno llamado "paso por objeto". Al parecer es similar al modelo usado en LISP.

¿Qué significa paso por objeto? ¿Qué diferencias existen entre paso por objeto, por valor, y por referencia?

IDis31
  • 1,076
  • 2
  • 10
  • 14
  • En javascript pasar un objeto por los argumentos es lo mismo que pasarle una referencia. En Python debe ser igual. Los tipos particulares de objetos pueden ser _Arrays_ o _Nodos_ en todos los lenguajes de programación (al menos los que yo sé). –  Oct 30 '16 at 20:07
  • @ArtEze Tengo entendido que lo que sucede en Python no es completamente comparable con lo que paso por valor y paso por referencia significan, habiendo diferencias clave entre los tres. – IDis31 Oct 30 '16 at 22:42
  • ¿Qué te hizo pensar eso? ¿En qué página web hablan sobre esas diferencias? –  Oct 30 '16 at 23:03
  • Aquí tienes una explicación bastante detallada sobre este asunto: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/ – José Antonio Riaza Valverde Oct 30 '16 at 23:06
  • 1
    @ArtEze El comentario de arriba es un ejemplo. – IDis31 Oct 30 '16 at 23:16

2 Answers2

3

Encontré una pregunta similar, quizás te sirva la respuesta que le dieron.

Entendiendo la ausencia de punteros en Python

En Python todo es un objeto creado en la memoria dinámica (mantenida automáticamente). Cuando llamas a una función los argumentos son pasados mediante sus punteros. Es lo que se conoce como convención de llamada por objeto.

En la otra respuesta, dice esto.

En general, los objetos de reservan en la memoria dinámica de los procesos, y las variables son referencias a ellos: casi casi que las referencias son abstracciones de los punteros, con algunas propiedades más.

Por este motivo, el pasaje de parámetros se hace siempre por referencia, por lo que no se necesitan punteros para esto.

Entonces en un comentario le responden esto.

falso, el paso de parámetros se hace por valor, pero se trata de valores referencia.

3

Primero, definiciones (mías, dado que yo vengo del mundo de C++, en donde no hay paso por nombre/objeto, así que adapto un poco las definiciones para poder compararlas):

  • Objeto: el trozo de memoria. Tiene una dirección de memoria, y no hay dos objetos con igual dirección de memoria (al menos, en C++).
  • Valor: contenido o estado de un objeto (es decir, lo que hay en el trozo de memoria).
  • Variable: nombre asociado a un objeto. Distinguir objetos por nombre es más fácil que por direcciones de memoria, ¿verdad? Manipular la variable es manipular el objeto referido por la variable.
  • Referencia: nombre asociado a una variable. Manipular la referencia manipula al objeto de su variable asociada. Equivalente a decir que es un nombre alternativo para un objeto existente.

Con ésto, pasemos a las diferencias (bajo el supuesto de que llamamos a una función, cuyo parámetro es recibido por valor, referencia o nombre/objeto respectivamente):

  • Paso por valor: crea una variable nueva, cuyo objeto es una copia de otro (dos cajas diferentes con igual valor/contenido; asignar modifica el contenido de la caja local).

  • Paso por referencia: se crea una referencia a la variable recibida (es decir, se crea otro nombre para el objeto recibido). Manipular la referencia, es manipular al "objeto compartido" (dos nombres para la misma caja; asignar modifica el contenido de la caja compartida).

  • Paso por objecto (o por nombre): se crea una variable nueva, que apunta al objeto recibido (dos cajas que apuntan al mismo objeto; asignar hace que la caja local apunte a un nuevo objeto, haciendo que el objeto original ya no sea compartido).

    La diferencia con el anterior es que, al ser una variable nueva, es reasignable, lo que significa que a = o (si a es una variable recibida por nombre, y o cualquier tipo de varible o referencia), a partir de ahora, hace que a apunte a o (a su objeto asociado) sin modificar al objeto compartido (que dejará de ser compartido a partir de ahora).

    Sin embargo, si a fuese una referencia o una variable normal, a = o hace que el valor del objeto apuntado por a, se substituya por el valor del objeto referido por o. Una referencia siempre comparte al objeto enviado al crearse la referencia, y esto no puede "evitarse" ni "cambiarse" de ningún modo (una referencia no puede convertirse en nombre de una caja diferente).

    En el paso por nombre, sin embargo, cada vez que se realiza una asignación, no se modifica el valor del objeto apuntado, sino que se apunta al nuevo objeto, dejando el objeto original huérfano si era su "última caja" (que luego, el recolector de basura, se debería encargar de eliminar).

Peregring-lk
  • 2,499
  • 1
  • 8
  • 11