Parámetros y argumentos
Recordemos nuestro último programa:
Python | |
---|---|
La salida de este programa sería algo como:
En este momento, el código principal del programa primero solicita el nombre del usuario y lo almacena en la variable nombre
.
Luego llama a la función hola()
. Llamar a la función hola()
significa ejecutar el código que está dentro de la función hola()
. Por lo tanto, de manera generalizada, llamar a una función significa usar dicha función.
En este caso, la función hola()
es la destinataria de la llamada, simplemente imprime un saludo en pantalla sin devolver ningún resultado. Así, en realidad, esta no es una función si no una subrutina.
Luego de la llamada a hola()
, el programa continúa con la ejecución de la siguiente línea en el código principal, que imprime el nombre del usuario en pantalla. Y luego termina la ejecución del programa.
Propongamos una mejora a nuestro programa. Hasta ahora, la función hola()
simplemente imprime un saludo en pantalla. Pero, ¿qué pasaría si quisiéramos que la función hola()
reciba un argumento que sea el nombre de la persona a la que se le dirige el saludo?
¿Con qué objetivo? Bueno, nuestro programa realiza la tarea principal de saludar al usuario, y aunque es una sola tarea, esta se efectúa en dos fragmentos de código diferentes.
Si generalizamos este detalle, podemos determinar que cada vez que un programa realice una tarea específica, esta debería ser encapsulada en una función que reciba los argumentos necesarios para realizar dicha tarea, y que devuelva un resultado si es necesario; pero que dicha tarea no sea extendida más allá de la función, y que los datos manipulados por la función sean locales a esta, para evitar efectos secundarios no deseados en otras partes del programa.
Parametrización de subrutinas y funciones
¿Por qué no consideramos parametrizar la subrutina de nuestro programa?
Es decir, ¿podemos personalizar el saludo para que tal vez tome el nombre del usuario como entrada y así poder no solo decir "¡Hola!" y en la siguiente línea el nombre de la persona, sino también agregar al "¡Hola!" el nombre de la persona y hacerlo todo en una línea?
Claro que podemos. Para ello, hagamos la siguiente modificación a nuestro código:
Python | |
---|---|
En este caso, primero se ingresa el nombre del usuario y se almacena en la variable nombre
, en la línea 6.
Luego, se llama a la subrutina hola()
pasando como argumento el valor almacenado en la variable nombre
, en la línea 7.
En este caso, la subrutina hola()
de la línea 2 recibe el argumento que es el nombre de la persona a la que se le dirige el saludo y lo almacena en el parámetro nombre
, en el contexto de la subrutina.
Es importante remarcar que el parámetro nombre
de la subrutina hola()
es local a la subrutina, lo que significa que solo existe dentro de la subrutina y no afecta a la variable nombre
del programa principal. Aunque se llamen igual, son dos variables diferentes que existen en contextos diferentes, donde el valor de la variable del argumento pasado es copiado al parámetro de la subrutina al momento de llamarla, y a partir de ahí si se modifica el valor del parámetro, no afecta al valor de la variable original del programa principal.
Por último, la función print()
de la línea 3 imprime un saludo personalizado con el nombre de la persona en pantalla.
Al finalizar la impresión, la subrutina finliza, el control vuelve al programa principal y se continúa con la ejecución de la siguiente línea en el código principal, que no hace nada más, por lo que el programa termina su ejecución.
La salida de nuestro nuevo programa seguiría siendo la misma:
La ventaja es que la lógica de nuestro programa ahora se encuentra encapsulada en dentro de la subrutina hola()
, que recibe un argumento y personaliza el saludo con el nombre de la persona a la que se dirige el saludo. De esta manera, el programa principal simplemente solicita el nombre del usuario y llama a la subrutina hola()
pasando el nombre del usuario como argumento, para personalizar el saludo con el nombre del usuario. No le importa saber al programa principal como debe comportarse la subrutina. Le basta con llamarla y darle los datos necesarios para que esta cumpla con su tarea.
¡Para recordar!
Siempre debes aplicar las buenas prácticas para definir los nombres de las variables y parámetros.
En este caso, hemos elegido el identificador nombre
para el parámetro de la función, ya que almacenará el nombre de la persona a la que se dirige el saludo.
Veamos cómo se ejecuta el programa con esta modificación:
Y así, hemos parametrizado nuestra subrutina hola()
para que reciba un argumento y personalice el saludo con el nombre de la persona a la que se dirige el saludo. De esta manera podemos hacer más dinámico nuestro programa y personalizar el saludo según el nombre ingresado por el usuario, además de hacerlo en una sola línea.
Nota que nuestro código ya no tiene la última línea que imprime el nombre, ya que ahora la subrutina hola()
se encarga de imprimir el saludo personalizado con el nombre del usuario.
Esta optimización del código permite unificar el comportamiento de la subrutina, en este caso el saludo personalizado, y encapsular su lógica completa dentro de ella, para hacerla más flexible y reutilizable en diferentes contextos, simplemente pasando el argumento adecuado al momento de invocarla.
¡Para recordar!
Las subrutinas y funciones pueden recibir argumentos que se almacenan en parámetros y que se utilizan dentro de la subrutina o función para realizar su tarea.
De esta manera, se pueden personalizar las subrutinas y funciones para que realicen tareas específicas según los valores de los argumentos que se les pasen al momento de invocarlas.
Parametrización de subrutinas y funciones con valores por defecto
Ahora, ¿qué pasaría si quisiéramos que nuestra subrutina imprimiera un saludo generalizado cuando no se le pasa un nombre específico?
¿Podríamos configurar su comportamiento para que imprima un saludo a todo el mundo, de manera predeterminada, o que imprima un saludo personalizado cuando se le indique a quien saludar?
¡Para recordar!
En el caso de que no se pase un argumento al invocar una subrutina o función, es posible asignar un valor por defecto al parámetro que recibiría dicho argumento, durante su definición, para ser utilizado de manera predeterminada durante la ejecución de dicha subrutina o función.
Recuerdas que con print()
había un valor predeterminado para sep
, para el separador, y había un valor predeterminado para end
, el final de línea. Nosotros también podemos recrear ese comportamiento con nuestro parámetros.
En nuestro caso, podríamos asignar un valor por defecto al parámetro nombre
de la función hola()
, para que si no se pasa un argumento al invocarla, se utilice ese valor por defecto.
Modifiquemos un poco el código y la lógica y comportamiento de nuestro programa:
Python | |
---|---|
En este caso, la función hola()
de la línea 2 recibe un parámetro nombre
con un valor por defecto "Mundo"
, que se utilizará si no se pasa un argumento al invocar la función.
En la línea 7, se invoca a la función hola()
sin pasar un argumento, por lo que se utilizará el valor por defecto "Mundo"
para personalizar el saludo.
Luego, en la línea 8, se solicita al usuario que ingrese su nombre y se almacena en la variable nombre
.
Finalmente, en la línea 9, se invoca a la función hola()
pasando como argumento el valor almacenado en la variable nombre
, para personalizar el saludo con el nombre del usuario.
Veamos como se ejecuta el programa con esta modificación:
Y así, hemos asignado un valor por defecto al parámetro nombre
de la función hola()
, para que si no se pasa un argumento al invocarla, se utilice ese valor por defecto. De esta manera, podemos personalizar el saludo con el nombre del usuario si se pasa un argumento, o con el valor por defecto si no se pasa un argumento.
¡Para recordar!
Es posible asignar valores por defecto a los parámetros de las subrutinas y funciones, para que se utilicen esos valores en caso de que no se pasen argumentos al invocarlas.
De esta manera, se pueden personalizar las subrutinas y funciones con valores por defecto que se utilizarán si no se pasan argumentos al invocarlas.