Python: Tuples

def nombre_funcion(parametro1[=valor_por_defecto], ...):
	bloque_de_código

nombre_funcion([parametro1=]valor_parametro_1, ...)

Para definir la función usamos def seguido de un nombre y, opcional, entre paréntesis los parámetros que recibe la función. Cada parámetro podemos especificar (opcional también) y valor por defecto, con lo cual si al llamar a la función no se pone ese parámetro se toma el valor indicado por defecto. Si no indicamos un valor por defecto y no ponemos un valor al llamar a la función se producirá una excepción .

Cuando llamamos a la función debemos poner los parámetros en el mismo orden que se han definido a menos que indiquemos el nombre del parámetro, que podremos poner el orden que queramos.

Una función siempre devuelve un valor, si no indicamos el comando return devuelve por defecto None.

In [1]: def conecta(router, ruser='admin, rpass):
   ...:     print('Conectando al router {} con usuario {} y contraseña {}...'.format(router, ruser, rpass))
   ...:

In [2]: conecta('192.168.1.1', 'admin', 'qwerty')
Conectando al router 192.168.1.1 con usuario admin y contraseña qwerty...

In [3]: conecta(rpass='qwerty', ruser='admin',router='192.168.1.1')
Conectando al router 192.168.1.1 con usuario admin y contraseña qwerty...

In [4]: conecta('192.168.1.1',rpass='qwerty', ruser='admin')
Conectando al router 192.168.1.1 con usuario admin y contraseña qwerty...

Cuando ponemos valores por defecto en la definición, a partir del parámetro que se ponga el valor por defecto, el resto obligatoriamente deben tener valor por defecto, si no, se produce un error de sintaxis:

In [1]: def conecta(router, ruser='admin', rpass):
   ...:     print('Conectando al router {} con usuario {} y contraseña {}...'.format(router, ruser, rpass))
   ...:
  File "<ipython-input-4-89827ff3f1f2>", line 1
    def conecta(router, ruser='admin', rpass):
               ^
SyntaxError: non-default argument follows default argument

este es un ejemplo correcto:

In [1]: def conecta(router, ruser='admin', rpass='qwerty'):
   ...:     print('Conectando al router {} con usuario {} y contraseña {}...'.format(router, ruser, rpass))
   ...:

In [2]: conecta('192.168.1.1')
Conectando al router 192.168.1.1 con usuario admin y contraseña qwerty...

In [3]: conecta('192.168.1.1', 'operador')
Conectando al router 192.168.1.1 con usuario operador y contraseña qwerty...

Podemos llamar a una función en vez de usar parámetros individuales, tomando esos valores desde una lista o un diccionario.

In [1]: def conecta(router, ruser='admin', rpass='qwerty'):
   ...:     print('Conectando al router {} con usuario {} y contraseña {}...'.format(router, ruser, rpass))
   ...:

In [2]: lista = ['192.168.1.1', 'admin', 'qwerty']

In [3]: conecta(*lista)
Conectando al router 192.168.1.1 con usuario admin y contraseña qwerty...

En el caso de las listas debemos preceder el nombre de la lista con un * y la lista debe contener el número exacto de elementos como parámetros pida la función, o menos si se han usado valores por defecto, si no se produce una excepción TypeError.

In [1]: def conecta(router, ruser='admin', rpass='qwerty'):
   ...:     print('Conectando al router {} con usuario {} y contraseña {}...'.format(router, ruser, rpass))
   ...:

In [2]: diccionario = {
    ...:     'router': '192.168.1.1',
    ...:     'ruser': 'operador1',
    ...:     'rpass': 'op_pass',
    ...: }

In [3]: conecta(**diccionario)
Conectando al router 192.168.1.1 con usuario operador1 y contraseña op_pass...

En el caso de los diccionarios debemos preceder el nombre con doble ** y el diccionario debe contener el número exacto de elementos como parámetros pida la función, o menos si se han usado valores por defecto, si no se produce una excepción TypeError.

Hay que tener cuidado con parámetros modificables (mutables) ya que se hace referencia al objeto principal y no una copia local, con un ejemplo se ve mejor:

In [1]: def funcion(otra_lista):
   ...:     print(otra_lista)
   ...:     otra_lista.append('nuevo valor')
   ...:

In [2]: mi_lista = ['valor viejo']

In [3]: funcion(mi_lista)
['valor viejo']

In [4]: mi_lista
Out[4]: ['valor viejo', 'nuevo valor']

Lo que pasa aquí es que tanto mi_lista como otra_lista apuntan al mismo contenido, con lo cual se modifica lo mismo se use el nombre que se use.

Por defecto Python primero busca la variable dentro de la función (variables locales) y si no la encuentra busca fuera, variables globales, pero SOLOpara leer su contenido, no para modificarlo. Si intentamos modificar una variable global dentro de una función se produce una excepción UnboundLocalError.

In [1]: cadena1 = "global"

In [2]: def funcion(cadena2):
   ...:     print("cadena1 = ", cadena1)
   ...:     print("cadena2 = ", cadena2)
   ...:
   ...:

In [3]: funcion('parametro')
cadena1 =  global
cadena2 =  parametro

Para modificar una variable global desde dentro de una función debemos indicar en la función que esa variable es global:

In [1]: cadena1 = "global"

In [2]: def funcion(cadena2):
    ...:     global cadena1
    ...:     cadena2 += '.funcion'
    ...:     cadena1 += '.funcion'
    ...:     print("cadena1 = ", cadena1)
    ...:     print("cadena2 = ", cadena2)
    ...:
    ...:

In [3]: funcion('parametro')
cadena1 =  global.funcion
cadena2 =  parametro.funcion

Más información en: funciones

Retro

Lugares

Redes

Sistemas

Varios