Tracks
/
Python
Python
/
Temario
/
Funciones
Fu

Funciones en Python

{one: "1 ejercicio", many: "%{count} ejercicios", other: "%{count} ejercicios"}

Acerca de Funciones

Una function es un bloque de código organizado y reutilizable que se usa para realizar una tarea concreta. Functions aportan una mejor modularidad a tu aplicación y un alto grado de reutilización de código. Python, como otros lenguajes de programación, tiene funciones integradas (print, map, etcétera) que están ya disponibles. También puedes definir tus propias funciones. Esas se llaman user-defined functions. Las funciones pueden hacer algo tan simple como imprimir un mensaje en la consola o pueden ser bastante complejas.

Para ejecutar el código que hay dentro de una función, tienes que llamar a la función, lo que se hace escribiendo el nombre de la función seguido de un par de paréntesis [()]. Los datos, conocidos como arguments, se pueden pasar a la función colocándolos dentro de los paréntesis. La definición de una función puede incluir cero o más parameters. Los parámetros definen qué argumento(s) acepta la función. Un parámetro define qué tipo de argumento se va a pasar. El argumento es el valor real que se pasa cuando se llama a la función. Las funciones pueden realizar tareas distintas según los argumentos que se pasen a los parámetros.

Una función también puede devolver un valor usando la palabra clave return. El valor que devuelve la función se conoce como el return value. El valor devuelto se devuelve a quien haya llamado a la función.

Creación

En Python, las funciones se crean con la palabra clave def. A la definición de la función le siguen el nombre de la función y un par de paréntesis [()]. Dentro de los paréntesis se especifican los parámetros, separados por comas. Después del paréntesis de cierre, se usan los dos puntos (:) para separar la firma de la función del cuerpo de la función.

El cuerpo de la función es un bloque de código que se ejecuta cuando se llama a la función. El cuerpo de la función va indentado. La indentación es importante porque Python se basa en ella para saber dónde termina ese bloque de código. Se puede devolver un valor desde la función usando la palabra clave return, que después puede usar quien haya llamado a la función.

def function_name(parameter1, parameter2, ...):
    # function body
    return parameter1 + parameter2

También podemos definir una función sin parámetros ni valor devuelto.

def function_name():
    # function body
    pass

Ten en cuenta que la función sí necesita un cuerpo, aunque el cuerpo no haga nada; de lo contrario, al intentar ejecutar el programa se producirá un error de indentación:

>>> def my_bodyless_func():
...      

File ~/temp.py:1
    
    ^
IndentationError: expected an indented block

Llamar a una función

Para llamar a una función, escribe el nombre de la función seguido de un par de paréntesis [()]. Los parámetros que se pasan a la función se colocan dentro de los paréntesis, separados por comas.

Fíjate en la siguiente función:

def greet():
    print("Hello")

La función anterior se puede llamar con la siguiente sintaxis:

>>> greet()
Hello

Los parámetros y sus argumentos

Los argumentos son los valores que se pasan a la función cuando se la llama. Pueden ser de cualquier tipo de datos, incluso otras funciones o clases.

Vamos a definir una función add que suma dos números:

def add(first, second):
    print(first + second)

Los parámetros first y second definen qué argumentos aceptará la función add. (Cabe señalar que las palabras parameter y argument a menudo se usan indistintamente, aunque de forma imprecisa). Cuando se llama a la función, se le pasan los argumentos. Tenemos que pasar argumentos para los dos parámetros; de lo contrario, se lanzará un TypeError.

>>> add(2, 3)
5

# Function can be called multiple times, with different parameters
>>> add(4, 3)
7
>>> add(5, 6)
11

# Passing an incorrect number of parameters will raise a `TypeError`
>>> add(2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() missing 1 required positional argument: 'second'

>>> add(2, 3, 4)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() takes 2 positional arguments but 3 were given

El valor devuelto

El valor devuelto es un valor que se devuelve a quien llamó a la función. Un return value puede ser de cualquier tipo de datos, incluidas otras funciones o clases. Quien llamó a la función puede usarlo para realizar más operaciones. Si una función no define explícitamente un return value, el intérprete de Python devolverá el valor None.

Vamos a definir una función add:

def add(first, second):
    return first + second

Podemos guardar el valor devuelto en una variable y luego imprimirlo:

>>> result = add(2, 3)
>>> print(result)
5
# Type of result is `int`
>>> type(result)
<class 'int'>

# We can also perform operations on the return value
>>> result * 2
10

# A function without an explicit return value will return `None`
>>> def log(message):
    print(message)

# Hello is printed because of print(message), but return value is `None`
>>> return_value = log("Hello")
Hello
>>> return_value
None

El uso de return sale inmediatamente de la función y devuelve el valor a quien la llamó.

>>> def show(first, second):
    print(first)
    return first
    print(second)

# second never gets printed, because the function exits after the return statement
>>> show(1, 2)
1

Modularidad

Los programas complejos se pueden descomponer en partes más pequeñas. Se pueden usar distintas funciones para realizar tareas concretas diferentes.

Supongamos que un programa tiene que realizar las siguientes tareas:

  • Calcular el área de un círculo
  • Calcular el área de un rectángulo
  • Calcular el área de un triángulo

Podemos descomponer el programa en partes más pequeñas.

def circle_area(radius):
    return 3.14 * radius * radius

def rectangle_area(length, breadth):
    return length * breadth

def triangle_area(base, height):
    return 0.5 * base * height

Ahora podemos llamar a las funciones en el orden que queramos.

>>> circle_area(2)
12.56
>>> triangle_area(2, 3)
3.0
>>> rectangle_area(2, 3)
6
>>> rectangle_area(1, 2) + circle_area(2) + triangle_area(1, 2)
15.56

El scope de las variables

Si una variable (o nombre) se define dentro de una función, solo será accesible dentro del scope de la función (o espacio de nombres local), aunque haya una variable con el mismo nombre fuera del scope de la función.

Las variables definidas fuera de una función, a nivel de módulo, se consideran dentro del espacio de nombres global. Las variables definidas fuera de una función pero dentro de una función o clase envolvente están en el espacio de nombres no local.

Python usa la LEGB Rule (Local, Enclosing, Global, Built-in) para resolver los nombres de las variables mientras se ejecuta un programa:

  1. Se busca en el espacio de nombres local (o de la función).
  2. Se busca en el espacio de nombres enclosing (o no local) si no se encuentra el nombre en local.
  3. Se busca en el espacio de nombres global (nivel de módulo) si el nombre no se encuentra en nonlocal/enclosing.
  4. Se busca en el espacio de nombres built-in (del programa o de todo Python) si el nombre no se encuentra en global.

Si el nombre sigue sin resolverse, Python lanzará una NameError exception.

# Global namespace.
general_favorite = "apples"


def alices_favorite():
   # Local namespace.  
   favorite = "cherries"
   
   # This works because Python will eventually find general_favorite in the global namespace.
   # Python will find 'print' in the built-in namespace.
   print(f'Alice has always liked {favorite}, but most people like {general_favorite}.')

   
def our_favorite_fruits():
    # Enclosing or nonlocal namespace.
    yours = "peaches"
    
    def my_favorite():
        # Local namespace.
        mine = "pears"
        
        # This works because Python will eventually find 'yours' in the enclosing/nonlocal namespace.
        print(f'My favorite is {mine}, but you like {yours} instead.')
        
        # This works because Python will eventually find 'general_favorite' in the global namespace.
        print(f'Everyone seems to like {general_favorite}')
    
    # This function is in the local namespace of the 'our_favorite_fruits' function.  
    my_favorite()

    
# This will raise NameError: name 'favorite' is not defined, because the variable favorite is local to alices_favorite.
print(favorite)

Si queremos que un nombre de variable sea accesible fuera del scope local de la función (o modificar una variable que se ha definido fuera del scope de la función), tenemos que usar la palabra clave global o nonlocal.

Usar la palabra clave global le indica a Python que empiece la búsqueda en el espacio de nombres global. Las asignaciones a la variable modificarán entonces la variable global, en lugar de crear una versión local. Cuando se usa global para declarar una variable, la variable se añade al espacio de nombres global. Por eso, global debe usarse con cautela, ya que añadir o modificar una variable global podría afectar a todo el demás código que use su valor.

La palabra clave nonlocal le indica a Python que busque o cree la variable en el espacio de nombres no local o envolvente. Se usa cuando una función está anidada dentro de otra función o clase y necesita acceder a las variables y al scope de la función externa.

Las funciones como objetos de primera clase

En Python, las funciones se pueden asignar a variables y pasar como argumentos a otras funciones. También se pueden usar como valores devueltos. Las funciones pueden colocarse además dentro de una secuencia (list, tuple, etc.) o como valor en un dict. Las funciones se pueden usar en cualquier lugar donde se pueda usar otro objeto. Esto se debe a que las funciones son objetos de primera clase. Como tales, llevan atributos especiales e incluso pueden definir sus propios atributos personalizados de lectura y escritura.

# print is a function

# A function can be assigned to a variable.
>>> function_as_variable = print
>>> function_as_variable("Hello")
Hello
>>> type(fake_print)
<class 'builtin_function_or_method'>

# Functions can be passed as an argument to another function.
>>> def check_print(func):
    func("Hello")
>>> check_print(print)
Hello

# Function can be used as an item in a sequence.
>>> my_list = [print, "Hello"]
>>> my_list[0]("Hello")
Hello

# Functions can be used as a value in a dictionary.
>>> my_dict = {"key": print}
>>> my_dict["key"]("Hello")
Hello

# Functions can be returned from a function.
>>> def return_func():
    return print
>>> return_func()("Hello")
Hello

Las funciones también pueden anidarse dentro de otras funciones.

def outer():
    num = 10
    
    # This is a nested, or "inner" function.
    def inner():
        print(num)
    
    # Outer function calling inner function
    inner()

La función interna puede acceder a la variable num definida en la función externa.

>>> outer()
10

Atributos especiales

Las funciones en Python tienen atributos especiales. Algunos de ellos son:

  • __name__: nombre de la función
  • __doc__: cadena de documentación de la función
  • __module__: módulo en el que se define la función
  • __globals__: diccionario de variables globales de la función
  • __code__: objeto de código que contiene las instrucciones de la función
>>> def add(first, second):
      return first + second

# Function name
>>> print.__name__
'print'
>>> len.__name__
'len'
>>> add.__name__
'add'

# Function documentation
>>> abs.__doc__
'Return the absolute value of the argument.'

# Module
>>> len.__module__
'builtins'
>>> add.__module__
'__main__'

La lista completa de atributos de funciones se puede encontrar en Python DataModel.

Editar en GitHub El enlace se abre en una nueva ventana o pestaña