Python: Funciones
Una función es un fragmento de código con un nombre asociado que realiza una serie de tareas y devuelve un valor. A los fragmentos de código que tienen un nombre asociado y no devuelven valores se les suele llamar procedimientos. En Python no existen los procedimientos, ya que cuando el programador no especifica un valor de retorno la función devuelve el valor None, equivalente al null de Java.
Además de ayudarnos a programar y depurar dividiendo el programa en partes las funciones también permiten reutilizar código.
En Python las funciones se declaran de la siguiente forma:
def mi_funcion(param1, param2): print param1 print param2
Es decir, la palabra clave def seguida del nombre de la función y entre paréntesis los argumentos separados por comas. A continuación, en otra línea, indentado y después de los dos puntos tendríamos las líneas de código que conforman el código a ejecutar por la función.
También podemos encontrarnos con una cadena de texto como primera línea del cuerpo de la función. Estas cadenas se conocen con el nombre de docstring (cadena de documentación) y sirven, como su nombre indica, a modo de documentación de la función.
def mi_funcion(param1, param2): """Esta funcion imprime los dos valores pasados como parametros""" print param1 print param2
Al declarar la función lo único que hacemos es asociar un nombre al fragmento de código que conforma la función, de forma que podamos ejecutar dicho código más tarde referenciándolo por su nombre. Es decir, a la hora de escribir estas líneas no se ejecuta la función. Para llamar a la función (ejecutar su código) se escribiría:
mi_funcion("hola", 2)
Es decir, el nombre de la función seguido de los valores que queramos pasar como parámetros entre paréntesis. La asociación de los parámetros y los valores pasados a la función se hace normalmente de izquierda a derecha: como a param1 le hemos dado un valor “hola” y param2 vale 2, mi_funcion imprimiría hola en una línea, y a continuación 2.
Sin embargo también es posible modificar el orden de los parámetros si indicamos el nombre del parámetro al que asociar el valor a la hora de llamar a la función:
mi_funcion(param2 = 2, param1 = "hola")
El número de valores que se pasan como parámetro al llamar a la función tiene que coincidir con el número de parámetros que la función acepta según la declaración de la función. En caso contrario Python se quejará:
>>> mi_funcion(“hola”)
Traceback (most recent call last):
File “<stdin>”, line 1, in <module>
TypeError: mi_funcion() takes exactly 2 arguments (1 given)
También es posible no obstante definir funciones con un número variable de argumentos o bien asignar valores por defecto a los parámetros para el caso de que no se indique ningún valor para ese parámetro al llamar a la función.
Los valores por defecto para los parámetros se definen situando un signo igual después del nombre del parámetro y a continuación el valor por defecto:
def imprimir(texto, veces = 1): print veces * texto
En el ejemplo anterior si no indicamos un valor para el segundo parámetro se imprimirá una sola vez la cadena que le pasamos como primer parámetro:
>>> imprimir(“hola”)
hola
si se le indica otro valor, será este el que se utilice:
>>> imprimir(“hola”, 2)
holahola
Para definir funciones con un número variable de argumentos colocamos un último parámetro para la función cuyo nombre debe precederse de un signo ‘*’:
def varios(param1, param2, *otros): for val in otros: print otros varios(1, 2) varios(1, 2, 3) varios(1, 2, 3, 4)
Esta sintaxis funciona creando una tupla (de nombre otros en el ejemplo) en la que se almacenan los valores de todos los parámetros extra pasados como argumento. Para la primera llamada, varios(1, 2), la tupla otros estaría vacía dado que no se han pasado más parámetros que los dos definidos por defecto, por lo tanto no se imprimiría nada. En la segunda llamada otros valdría (3), y en la tercera (3, 4).
También se puede preceder el nombre del último parámetro con ‘**’, en cuyo caso en lugar de una tupla se utilizaría un diccionario. Las claves de este diccionario serían los nombres de los parámetros indicados al llamar a la función y los valores del diccionario, los valores asociados a estos parámetros:
def varios(param1, param2, **otros): for i in otros.items(): print i varios(1, 2, tercero = 3)
Los que conozcáis algún otro lenguaje de programación os estaréis preguntando si en Python al pasar una variable como argumento de una función estas se pasan por referencia o por valor. En el paso por referencia lo que se pasa como argumento es una referencia o puntero a la variable, es decir, la dirección de memoria en la que se encuentra el contenido de la variable, y no el contenido en si. En el paso por valor, por el contrario, lo que se pasa como argumento es el valor que contenía la variable.
La diferencia entre ambos estriba en que en el paso por valor los cambios que se hagan sobre el parámetro no se ven fuera de la función, dado que los argumentos de la función son variables locales a la función que contienen los valores indicados por las variables que se pasaron como argumento. Es decir, en realidad lo que se le pasa a la función son copias de los valores y no las variables en si.
Si quisiéramos modificar el valor de uno de los argumentos y que estos cambios se reflejaran fuera de la función tendríamos que pasar el parámetro por referencia.
En C los argumentos de las funciones se pasan por valor, aunque se puede simular el paso por referencia usando punteros. En Java también se usa paso por valor, aunque para las variables que son objetos lo que se hace es pasar por valor la referencia al objeto, por lo que en realidad parece paso por referencia.
En Python también se utiliza el paso por valor de referencias a objetos, como en Java, aunque en el caso de Python, a diferencia de Java, todo es un objeto (para ser exactos lo que ocurre en realidad es que al objeto se le asigna otra etiqueta o nombre en el espacio de nombres local de la función).
Sin embargo no todos los cambios que hagamos a los parámetros dentro de una función Python se reflejarán fuera de esta, ya que hay que tener en cuenta que en Python existen objetos inmutables, como las tuplas, por lo que si intentáramos modificar una tupla pasada como parámetro lo que ocurriría en realidad es que se crearía una nueva instancia, por lo que los cambios no se verían fuera de la función.
Veamos un pequeño programa para demostrarlo:
def f(x, y): x = x + 3 y.append(23) print x, y x = 22 y = [22] f(x, y) print x, y
El resultado de la ejecución de este programa sería
25 [22, 23]
22 [22, 23]
Como vemos la variable x no conserva los cambios una vez salimos de la función porque los enteros son inmutables en Python. Sin embargo la variable y si los conserva, porque las listas son mutables.
En resumen: los valores mutables se comportan como paso por referencia, y los inmutables como paso por valor.
Con esto terminamos todo lo relacionado con los parámetros de las funciones. Veamos ahora cómo devolver valores, para lo que se utiliza la palabra clave return:
def sumar(x, y): return x + y print sumar(3, 2)
Como vemos esta función tan sencilla no hace otra cosa que sumar los valores pasados como parámetro y devolver el resultado como valor de retorno.
También podríamos pasar varios valores que retornar a return.
def f(x, y): return x * 2, y * 2 a, b = f(1, 2)
Sin embargo esto no quiere decir que las funciones Python puedan devolver varios valores, lo que ocurre en realidad es que Python crea una tupla al vuelo cuyos elementos son los valores a retornar, y esta única variable es la que se devuelve.







Oh yeah!!
YA pensé que tenías abandonadillo el cursillo!
Mil gracias!
Muy buena info, gracias
Revisa el estilo del artículo ya que resulta poco coherente.
Si es un curso para programadores en otros lenguajes explicar que es una función sobra y si el público objetivo son no programadores hablar del “null de java” es como mentar la “junta de la trócola”.
Es un tutorial para todos los lectores de Mundo geek interesados en aprender Python, sean o no programadores.
Si no conoces otro lenguaje de programación basta con que ignores los comentarios sobre otros lenguajes. Si los conoces, es una ayuda para entender cómo funciona Python.
Y viceversa, si sabes lo que es una función puedes ignorar su definición.
[...] recurriendo a funciones con parámetros por defecto, a la sintaxis *params o **params explicada en Python: Funciones o bien usando decoradores (mecanismo que veremos más [...]
[...] variable de argumentos a un método de forma transparente, de la misma forma en que lo haríamos en otros lenguajes como Python. Basta añadir “…” después del [...]
Hola, buenas. Me parece genial tu tutorial y sobretodo que compartas con todo el mundo tu conocimiento de python, creo que tu eres la persona indicada para resolver una cuestión que me trae algo de cabeza. Te comento: sabes como hacer una función swap (al estilo C)? en teoría todo lo de la mutabilidad está muy bien, pero no comprendo cómo nadie (ni siquiera Guido) explica una cosa que aparente es muy fácil caer en ella. Mira mi ejemplo:
#prueba.py
class Punto:
pass
def swap (a, b):
a, b = b, a
def principal ():
p1 = Punto()
p2 = Punto()
print p1, p2
swap(p1, p2)
print p1, p2
if __name__==”__main__”:
principal () # esto lo hacemos para que los
# objetos pasados no sean variables globales
# del modulo
Muchas gracias tío.
Perdón por no poner la identación , wl wordpress este es traicionero.
Gracias nuevamente
@Manu Castro podrías meter ambos valores dentro de un diccionario, por ejemplo, que es mutable.
O podrías devolver ambos valores y hacer
a, b = swap(a, b).También puedes buscar en Google la implementación de un decorador que simulaba el paso por referencia.
O sea que entiendo que aunque las clases creadas por el usuario sean mutables no se puede hacer swap de objetos creados a partir de ellas…Según observo tampoco se puede hacer para objetos lista (type = []), aunque también son mutables. Vamos que no se podía hacer era algo obvio, lo que no sabía es el porqué ….. De todas formas muchas gracias Raúl.
Estoy haciendo un programa el cual lee un valores de un archivo
def readconfig():
f=open(“config.txt”)
pc=f.readline(1)
port=f.readline(2)
print “el archivo de configuracion ha sido leido”, port
f.close()
return pc, port
pero el port que esta en la linea 2 del archivo no
es leída, me podrían ayudar no se cual sea mi error