Bienvenidos sean a este post, hoy continuaremos con las formas de trabajo de los parametros de ingreso de las funciones.
Nuestro primer caso sera ver como es trabajar con la combinacion de distintos parametros de ingreso, veamos el siguiente ejemplo creando un archivo llamado args.py y agregando el siguiente codigo:
args.py
def funcion(a, b, c=7, *args, **pcargs) :
print('a, b, c: ', a, b, c)
print('args: ', args)
print('pcargs: ', pcargs)
funcion(1, 2, 3, *(5, 7, 9),**{'A':'a', 'B':'b'})
funcion(1, 2, 3, 5, 7, 9, A='a', B='b')
Definimos la funcion y como pueden ver tienen varios tipos de argumentos, dos de tipo posicional, uno de palabras clave o con valor predeterminado, uno de argumentos variables y otro de palabras clave solo, despues mostraremos los tres tipos de argumentos separados por tres print, observen que en cada print mostramos la identificacion para saber cual es cual, despues tenemos dos lineas que seran para usar la funcion y le pasamos distintos valores, en realidad las dos lineas son iguales pero solamente que en la segunda linea podemos ver como el lenguaje se encargara de interpretar los dos informados y asignarlos correctamente, probemos para ver como es su salida:
tinchicus@dbn001vrt:~/python$ python3 args.py
a, b, c: 1 2 3
args: (5, 7, 9)
pcargs: {'A': 'a', 'B': 'b'}
a, b, c: 1 2 3
args: (5, 7, 9)
pcargs: {'A': 'a', 'B': 'b'}
tinchicus@dbn001vrt:~/python$
Observen como la salida son exactamente iguales pero si observan en el segundo caso, el lenguaje se encargo de estructurar la informacion ingresada acorde a como lo establecimos pero tengan en cuenta que los identificadores de las palabraas clave establecen el limite para los argumetnos variables pero sino lo pasamos nos devolvera un error como vimos en el post anterior, pasemos al siguiente tema.
En este caso hablaremos sobre unas generalizaciones adicionales sobre el desempaque, para ver este tema primero vamos a definir la siguiente funcion en el interprete:
>>> def adicional(*args, **pcargs) :
... print(args)
... print(pcargs)
...
>>>
En esta ocasion creamos una funcion que recibira argumentos y palabras clave variables y despues solo las mostrara en pantalla, pasemos a crear unas variables:
>>> args1 = (1, 2, 3)
>>> args2 = [4, 5]
>>> pcargs1 = dict(opcion1=10, opcion2=20)
>>> pcargs2 = {'opcion3':30}
>>>
En este caso vamos a crear una serie distinta de variables de todo tipo, nuestro siguiente paso sera pasar todas estas variables a nuestra funcion:
>>> adicional(*args1, *args2, **pcargs1, **pcargs2)
(1, 2, 3, 4, 5)
{'opcion1': 10, 'opcion2': 20, 'opcion3': 30}
>>>
Observen como le pasamos las variables con los asteriscos que corresponden al tipo de argumento variable, esto hara que el lenguaje desempaque cada uno de ellos y los convierta en uno solo llamado args y pcargs dependiendo del tipo, como pueden ver en la salida tenemos cada uno creado y con los datos correctamente asignados, pasemos a nuestro ultimo caso.
Una cosa que siempre debemos hacer en python es definir los valores predeterminados al momento de declarar la definicion pero llamadas subsecuentes a esta funcion puede tener extrañas conductas sobre los valores dependiendo de la mutabildad de los valores predeterminados, para esta ocasion vamos a hacer algo diferente, para ello vamos a crear un archivo y le ingresaremos el suguiente codigo:
mutable.py
def funcion(a=[], b={}) :
print(a)
print(b)
print('#' * 12)
a.append(len(a))
b[len(a)] = len(a)
En este caso creamos una funcion llamada funcion y tendra dos argumentos mutables pero vacios, en la funcion mostraremos los valores de los argumentos y por ultimo una serie de 12 numerales (#) para crear una division, luego viene lo divertido, en este caso a la lista a le agregamos la longitud de la misma, luego al diccionario b le pasamos como clave el tamaño de la lista a y como dato el tamaño de a, con esto terminamos con la funcion, vayamos al interprete y ejecutemos la siguiente linea:
>>> from mutable import funcion
Esta linea importa la funcion que generamos recien del archivo mutable.py, nuestro siguiente paso sera ejecutar la funcion vacia:
>>> funcion()
[]
{}
############
>>>
Pero si lo volvemos a ejecutar sucedera esto:
>>> funcion()
[0]
{1: 1}
############
>>>
Y si lo volvemos a ejecutar nos suceder la siguiente:
>>> funcion()
[0, 1]
{1: 1, 2: 2}
############
>>>
Como pueden ver a medida que vayamos llamando a la funcion sin informacion este se encargara de seguir agregando informacion en base a las llamadas que hagamos, veamos que sucede si llamamos a la funcion pero con valores:
>>> funcion(a=[1,2,3], b={'B':1})
[1, 2, 3]
{'B': 1}
############
>>>
Aca podemos ver como no trajo ninguno de los valores anteriores y los reemplazo con los nuevos pero que pasa si lo ejecutamos nuevamente vacio:
>>> funcion()
[0, 1, 2]
{1: 1, 2: 2, 3: 3}
############
>>>
Como pueden observar los valores predeterminados los retenemos en memoria por mas que le pasemos la funcion con valores, pero como podemos evitar esta conducta?, una solucion por convencion es la siguiente:
def funcion(a=None) :
if a is None:
a = []
... el resto de las instrucciones.
En este caso definimos a la variable y el valor predeterminado es None, lo primero que haremos es verificar si a es igual a None y en caso de ser verdadero procede a generar una lista vacia de lo contrario procede a procesar el valor informado, evitando lo sucedido anteriormente.
En resumen, hoy hemos completado las formas de ingresar valores o parametros por medio de los argumentos de las funciones, hemos visto primero como utilizar multiples tipos de argumentos y como el lenguaje los diferencia, luego hemos visto como podemos enviar varios tipos de argumentos variables, como el lenguaje los desempaca y los vuelve a juntar en uno solo y por ultimo como podemos caer en la trampa de los datos mutables con valores predeterminados, y como solucionarlo, espero les haya sido de utilidad sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.


Donación
Es para mantenimento del sitio, gracias!
$1.00
