Fundamentos de las Funciones de Python

PythonPythonBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, aprenderás cómo definir y usar funciones de Python. Empezaremos con ejemplos simples y gradualmente aumentaremos la complejidad.

Comencemos!

Logros

  • Funciones de Python

Definir una función de Python

Para definir una función de Python, debes usar la palabra clave def seguida del nombre de la función y un conjunto de paréntesis que pueden contener argumentos. El cuerpo de la función está indentado y sigue el carácter :.

Abra un nuevo intérprete de Python.

python3

Aquí hay un ejemplo de una función simple que toma un solo argumento x y devuelve el cuadrado de x:

def square(x):
  return x ** 2

En este ejemplo, la función square toma un solo argumento x y devuelve el cuadrado de x. El valor se devuelve al llamador usando la declaración return.

Para llamar a una función, simplemente use el nombre de la función seguido de un conjunto de paréntesis y cualquier argumento necesario. Por ejemplo:

result = square(5)  ## result is 25
print(result)

Si una función no tiene una declaración return, devolverá None por defecto. Por ejemplo:

def square(x):
  print(x ** 2)

result = square(5)  ## result is None
print(result)

Debes conocer la diferencia entre las declaraciones return y print. La declaración print se utiliza para imprimir el valor en la pantalla, pero la declaración return se utiliza para devolver el valor de la función.

También es posible usar la declaración return para terminar la ejecución de una función temprano. Por ejemplo:

def find_first_positive(numbers):
  for number in numbers:
    if number > 0:
      return number
  return None

result = find_first_positive([-1, -2, 3, -4, 5])  ## result is 3
print(result)

En este ejemplo, la función find_first_positive devuelve el primer número positivo de la lista numbers, o None si no se encuentran números positivos. La declaración return termina la ejecución de la función tan pronto como se encuentra un número positivo.

Argumentos de función

A veces, es útil especificar valores predeterminados para los argumentos de una función. De esta manera, se puede llamar a la función sin pasar un valor para ese argumento, y se usará el valor predeterminado en su lugar.

Aquí hay un ejemplo de una función que calcula el área de un rectángulo. Toma dos argumentos: la longitud y el ancho del rectángulo. Podemos especificar valores predeterminados para ambos argumentos, de modo que la función se puede llamar con solo un argumento si la longitud y el ancho son iguales:

def rectangle_area(length, width=1):
  return length * width

print(rectangle_area(5))  ## Output: 5
print(rectangle_area(5, 2))  ## Output: 10

En este ejemplo, el argumento width tiene un valor predeterminado de 1. Si la función se llama con solo un argumento, se usa el valor predeterminado de 1 para width.

Prueba por ti mismo: define una función llamada power que tome dos argumentos: una base x y un exponente n. Haz que el argumento del exponente sea opcional, con un valor predeterminado de 2. Luego, llama a la función con diferentes valores para la base y el exponente.

def power(x, n=2):
  return x ** n

print(power(2))  ## Output: 4
print(power(2, 3))  ## Output: 8

Indicación de tipo de argumento

En Python, las indicaciones de tipo de argumento de función indican el tipo esperado de un argumento pasado a una función. Fueron introducidas en Python 3.5 y se denotan por dos puntos seguidos del tipo, colocado después del nombre del argumento en la definición de la función.

Las indicaciones de tipo son opcionales y no afectan el comportamiento en tiempo de ejecución del código. Se utilizan principalmente por herramientas como IDEs y Linter para proporcionar un mejor análisis de código y sugerencias de autocompletado.

Por ejemplo, considera la siguiente función que toma dos argumentos, un entero y una cadena, y devuelve su concatenación:

def concatenate(a: int, b: str) -> str:
    return str(a) + b

print(concatenate(1, "world")) ## "1world"

En este ejemplo, las indicaciones de tipo int y str indican que el primer argumento a debe ser un entero y el segundo argumento b debe ser una cadena.

Las indicaciones de tipo también se pueden utilizar con clases y sus instancias, por ejemplo:

class MyClass:
    pass

def my_function(a: MyClass) -> None:
    pass

Es importante mencionar que, las indicaciones de tipo son opcionales y no afectan el comportamiento en tiempo de ejecución del código. Se utilizan principalmente por herramientas como IDEs y Linter para proporcionar un mejor análisis de código y sugerencias de autocompletado.

Además, Python tiene un módulo llamado typing que contiene tipos útiles como List, Tuple, Dict, Set, etc. que se pueden utilizar para dar pistas sobre los tipos de elementos en una colección.

from typing import List, Tuple
def my_function(a: List[int], b: Tuple[str, int]) -> None:
    pass

Es una buena práctica utilizar indicaciones de tipo en tu código para hacerlo más legible y mantenible.

Docstring

Una docstring es una literal de cadena que aparece como la primera declaración en una definición de módulo, función, clase o método. Dicha docstring se convierte en el atributo especial __doc__ de ese objeto.

Las docstrings se utilizan para documentar el código y se escriben en texto plano. Están encerradas en triples comillas """ y por lo general se colocan al principio de la definición de la función.

def my_function():
    """This is a docstring."""
    pass

Las docstrings suelen contener una breve descripción de la función, sus argumentos y su valor de retorno. También pueden contener una descripción más detallada del comportamiento de la función.

def my_function(a: int, b: int) -> int:
    """Return the sum of a and b.

    Args:
        a (int): The first number.
        b (int): The second number.

    Returns:
        int: The sum of a and b.
    """
    return a + b

Devolviendo múltiples valores

En Python, una función puede devolver múltiples valores utilizando una tupla. Aquí hay un ejemplo de una función que calcula los valores mínimo y máximo de una lista:

def min_max(numbers):
  return min(numbers), max(numbers)

nums = [1, 2, 3, 4, 5]
min_val, max_val = min_max(nums)
print("Valor mínimo:", min_val)  ## Salida: "Valor mínimo: 1"
print("Valor máximo:", max_val)  ## Salida: "Valor máximo: 5"

En este ejemplo, la función min_max devuelve una tupla que contiene los valores mínimo y máximo de la lista numbers. La tupla se desempaqueta en las variables min_val y max_val cuando se llama a la función.

Aquí hay otro ejemplo de devolución de múltiples valores de una función:

def get_student_info(name):
  if name == "John":
    return "John", "Doe", "Computer Science"
  elif name == "Jane":
    return "Jane", "Smith", "Physics"
  else:
    return "Desconocido", "Desconocido", "Desconocido"

first_name, last_name, major = get_student_info("John")
print("Nombre:", first_name)  ## Salida: "Nombre: John"
print("Apellido:", last_name)  ## Salida: "Apellido: Doe"
print("Materia:", major)  ## Salida: "Materia: Computer Science"

first_name, last_name, major = get_student_info("Jane")
print("Nombre:", first_name)  ## Salida: "Nombre: Jane"
print("Apellido:", last_name)  ## Salida: "Apellido: Smith"
print("Materia:", major)  ## Salida: "Materia: Physics"

first_name, last_name, major = get_student_info("Bob")
print("Nombre:", first_name)  ## Salida: "Nombre: Desconocido"
print("Apellido:", last_name)  ## Salida: "Apellido: Desconocido"
print("Materia:", major)  ## Salida: "Materia: Desconocido"

En este ejemplo, la función get_student_info toma el nombre de un estudiante y devuelve una tupla que contiene el nombre, el apellido y la materia del estudiante. La tupla se desempaqueta en variables separadas cuando se llama a la función.

Si el nombre del estudiante no es reconocido, la función devuelve una tupla con valores de "Desconocido".

Argumentos con palabras clave

En Python, puedes especificar los argumentos de una función utilizando "argumentos con palabras clave". Cuando utilizas argumentos con palabras clave, especificas el nombre del argumento seguido del valor, y los argumentos pueden ser proporcionados en cualquier orden.

Aquí hay un ejemplo de una función que toma dos argumentos: un nombre y un mensaje:

def greet(name, message):
  print("Hello, " + name + "! " + message)

greet(message="¿Cómo estás?", name="John")  ## Salida: "Hello, John! ¿Cómo estás?"

En este ejemplo, la función greet se llama con los argumentos "John" y "¿Cómo estás?", pero los argumentos se proporcionan en un orden diferente al que se define en la función. Al utilizar argumentos con palabras clave, puedes especificar los argumentos en cualquier orden y hacer que el código sea más legible.

También puedes mezclar argumentos con palabras clave con argumentos posicionales, siempre y cuando los argumentos posicionales se proporcionen primero. Por ejemplo:

def greet(name, message):
  print("Hello, " + name + "! " + message)

greet("John", message="¿Cómo estás?")  ## Salida: "Hello, John! ¿Cómo estás?"

En este ejemplo, el argumento name se proporciona como un argumento posicional, mientras que el argumento message se proporciona como un argumento con palabra clave.

Los argumentos con palabras clave son especialmente útiles cuando una función tiene un gran número de argumentos, o cuando los argumentos tienen valores predeterminados. Por ejemplo:

def create_user(name, age=18, gender="unknown"):
  print("Creating user:", name, age, gender)

create_user("John")  ## Salida: "Creating user: John 18 unknown"
create_user("Jane", gender="female")  ## Salida: "Creating user: Jane 18 female"
create_user("Bob", 25, "male")  ## Salida: "Creating user: Bob 25 male"

En este ejemplo, la función create_user toma tres argumentos: name, age y gender. Los argumentos age y gender tienen valores predeterminados, por lo que son opcionales. Al utilizar argumentos con palabras clave, puedes especificar solo los argumentos que quieres proporcionar, y los valores predeterminados se utilizarán para el resto.

Args y Kwargs

En Python, puedes utilizar la sintaxis *args y **kwargs para definir una función que puede tomar un número variable de argumentos.

La sintaxis *args se utiliza para pasar un número variable de argumentos no con palabras clave a una función. Por ejemplo:

def print_numbers(*args):
  for arg in args:
    print(arg)

print_numbers(1, 2, 3, 4, 5)  ## Salida: 1, 2, 3, 4, 5
print_numbers(10, 20, 30)  ## Salida: 10, 20, 30

En este ejemplo, la función print_numbers toma un número variable de argumentos y los imprime en la consola. La sintaxis *args se utiliza para definir la función, y los argumentos se pasan como una tupla a la función.

La sintaxis **kwargs se utiliza para pasar un número variable de argumentos con palabras clave a una función. Por ejemplo:

def print_keywords(**kwargs):
  for key, value in kwargs.items():
    print(key, ":", value)

print_keywords(name="John", age=30, city="New York")
## Salida:
## name : John
## age : 30
## city : New York

print_keywords(country="USA", population=327000000)
## Salida:
## country : USA
## population : 327000000

En este ejemplo, la función print_keywords toma un número variable de argumentos con palabras clave y los imprime en la consola. La sintaxis **kwargs se utiliza para definir la función, y los argumentos se pasan como un diccionario a la función.

Puedes mezclar la sintaxis *args y **kwargs con otros argumentos en una definición de función, siempre y cuando los argumentos *args y **kwargs se proporcionen al final. Por ejemplo:

def print_info(title, *args, **kwargs):
  print(title)
  for arg in args:
    print(arg)
  for key, value in kwargs.items():
    print(key, ":", value)

print_info("Person", "John", "Jane", "Bob", age=30, city="New York")
## Salida:
## Person
## John
## Jane
## Bob
## age : 30
## city : New York

En este ejemplo, la función print_info toma un argumento fijo title, seguido de un número variable de argumentos no con palabras clave (*args) y un número variable de argumentos con palabras clave (**kwargs). Los argumentos se pasan a la función en el orden en que se definen: primero title, luego *args, y finalmente **kwargs.

La sintaxis *args y **kwargs puede ser útil cuando quieres definir una función flexible que puede aceptar un número variable de argumentos. También pueden hacer que el código sea más legible al permitirte evitar el uso de nombres de argumentos codificados en duro en la definición de la función.

Aquí hay un ejemplo de una función que utiliza *args y **kwargs para crear un diccionario de argumentos:

def create_dict(**kwargs):
  return kwargs

my_dict = create_dict(name="John", age=30, city="New York")
print(my_dict)  ## Salida: {'name': 'John', 'age': 30, 'city': 'New York'}

my_dict = create_dict(a=1, b=2, c=3)
print(my_dict)  ## Salida: {'a': 1, 'b': 2, 'c': 3}

En este ejemplo, la función create_dict toma un número variable de argumentos con palabras clave y los devuelve como un diccionario. La sintaxis **kwargs se utiliza para definir la función, y los argumentos se pasan como un diccionario a la función.

También puedes utilizar el operador * para "desempaquetar" una lista o tupla en argumentos separados cuando llamas a una función. Por ejemplo:

def print_numbers(*args):
  for arg in args:
    print(arg)

numbers = [1, 2, 3, 4, 5]
print_numbers(*numbers)  ## Salida: 1, 2, 3, 4, 5

tuple_of_numbers = (10, 20, 30)
print_numbers(*tuple_of_numbers)  ## Salida: 10, 20, 30

En este ejemplo, el operador * se utiliza para desempaquetar la lista numbers y la tupla tuple_of_numbers en argumentos separados cuando se llama a la función print_numbers.

También puedes utilizar el operador ** para "desempaquetar" un diccionario en argumentos con palabras clave cuando llamas a una función. Por ejemplo:

def print_keywords(**kwargs):
  for key, value in kwargs.items():
    print(key, ":", value)

my_dict = {'name': 'John', 'age': 30, 'city': 'New York'}
print_keywords(**my_dict)
## Salida:
## name : John
## age : 30
## city : New York

another_dict = {'country': 'USA', 'population': 327000000}
print_keywords(**another_dict)
## Salida:
## country : USA
## population : 327000000

En este ejemplo, el operador ** se utiliza para desempaquetar los diccionarios my_dict y another_dict en argumentos con palabras clave cuando se llama a la función print_keywords.

Funciones lambda

En Python, puedes utilizar "funciones lambda" para crear funciones anónimas. Las funciones lambda son funciones pequeñas que no tienen un nombre y por lo general se definen y se llaman en una sola línea de código.

Aquí hay un ejemplo de una función lambda que toma dos argumentos y devuelve su suma:

sum = lambda x, y: x + y

result = sum(1, 2)  ## result es 3

En este ejemplo, la palabra clave lambda se utiliza para definir una función lambda que toma dos argumentos x e y y devuelve su suma. La función lambda se asigna a la variable sum y se puede llamar como cualquier otra función.

¿Podrías usar una función normal en lugar de una función lambda para definir la misma función?

def sum(x, y):
  return x + y

result = sum(1, 2)  ## result es 3

Las funciones lambda a menudo se utilizan como un atajo para definir funciones simples. Son especialmente útiles cuando quieres pasar una función como argumento a otra función, o cuando quieres definir una función en línea.

Aquí hay un ejemplo de uso de una función lambda como argumento a la función sorted:

words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=lambda x: len(x))
print(sorted_words)  ## Salida: ['apple', 'date', 'banana', 'cherry']

En este ejemplo, la función sorted toma una lista de palabras y una función "key" que especifica cómo deben ordenarse las palabras. La función lambda pasada como función key devuelve la longitud de cada palabra y las palabras se ordenan según su longitud.

Aquí hay un ejemplo de definición de una función lambda en línea:

result = (lambda x: x ** 2)(5)  ## result es 25

En este ejemplo, la función lambda toma un solo argumento x y devuelve el cuadrado de x. La función lambda se define y se llama en una sola línea de código y el result se asigna a la variable result.

Las funciones lambda a menudo se utilizan en Python para funciones cortas y simples que no necesitan ser reutilizadas en otro lugar del código. Son una forma conveniente de definir funciones pequeñas al vuelo, sin necesidad de definir una función separada utilizando la palabra clave def.

Alcance local y global

En Python, las variables definidas dentro de una función son "locales" a la función y solo están disponibles dentro de la función. Las variables definidas fuera de una función son "globales" y están disponibles en todo el programa.

Aquí hay un ejemplo de una variable global:

message = "Hello, world!"

def greet():
  print(message)

greet()  ## Salida: "Hello, world!"

En este ejemplo, la variable message se define fuera de la función greet, por lo que es una variable global. La función greet puede acceder e imprimir la variable message, porque está disponible en todo el programa.

Aquí hay un ejemplo de una variable local:

def greet(name):
  message = "Hello, " + name + "!"
  print(message)

greet("John")  ## Salida: "Hello, John!"
print(message)  ## Salida: NameError: name 'message' is not defined

En este ejemplo, la variable message se define dentro de la función greet, por lo que es una variable local. La función greet puede acceder e imprimir la variable message, pero no está disponible fuera de la función. Si intentas acceder a la variable message fuera de la función, obtendrás un NameError porque la variable no está definida.

También puedes usar la palabra clave global para modificar una variable global dentro de una función. Por ejemplo:

message = "Hello, world!"

def greet():
  global message
  message = "Hello, Python!"
  print(message)

greet()  ## Salida: "Hello, Python!"
print(message)  ## Salida: "Hello, Python!"

En este ejemplo, la función greet utiliza la palabra clave global para modificar la variable global message. La función greet imprime el valor modificado de message, y el valor de message también se modifica fuera de la función.

En general, es una buena idea evitar usar variables globales, porque pueden hacer que el código sea más difícil de entender y mantener. Por lo general, es mejor pasar variables a funciones como argumentos y devolverlas como resultados, en lugar de modificar variables globales.

Usar una función como argumento para otra función

En Python, puedes pasar una función como argumento a otra función. Esto se llama una "función de orden superior". Aquí hay un ejemplo de una función que toma otra función como argumento y la llama múltiples veces:

def greet(name):
  print("Hello, " + name + "!")

def call(func, args):
  for arg in args:
    func(arg)

names = ["John", "Jane", "Bob"]
call(greet, names)  ## Salida: "Hello, John!", "Hello, Jane!", "Hello, Bob!"

En este ejemplo, la función call toma dos argumentos: una función func y una lista de argumentos args. Llama a la función func con cada elemento de la lista args como argumento.

Prueba hacerlo tú mismo: define una función llamada apply que tome una función y una lista de números, y devuelva una nueva lista que contenga el resultado de aplicar la función a cada elemento de la lista.

def square(x):
  return x ** 2

def apply(func, numbers):
  result = []
  for number in numbers:
    result.append(func(number))
  return result

numbers = [1, 2, 3, 4, 5]
squared_numbers = apply(square, numbers)
print(squared_numbers)  ## Salida: [1, 4, 9, 16, 25]

Este paso puede ser un poco difícil, no te preocupes si no puedes resolverlo. Puedes saltarlo y volver a él más tarde.

Resumen

Ahora deberías tener una buena comprensión de cómo trabajar con funciones de Python. Aquí hay algunos de los puntos claves:

  1. Las funciones de Python son bloques de código que se pueden definir, llamar y reutilizar.
  2. Puedes definir una función usando la palabra clave def, seguida del nombre de la función y los argumentos.
  3. El cuerpo de la función debe estar indentado y puedes usar la palabra clave return para devolver un valor desde la función.
  4. Puedes especificar los argumentos de la función usando "argumentos con palabras clave", lo que te permite especificar el nombre y el valor del argumento al llamar a la función.
  5. Puedes usar la sintaxis *args para definir una función que puede tomar un número variable de argumentos no con palabras clave, y la sintaxis **kwargs para definir una función que puede tomar un número variable de argumentos con palabras clave.
  6. Puedes usar la palabra clave lambda para crear funciones anónimas que se definen y se llaman en una sola línea de código.
  7. En Python, las variables definidas dentro de una función son locales a la función y solo están disponibles dentro de la función. Las variables definidas fuera de una función son globales y están disponibles en todo el programa.
  8. En general, es una buena idea evitar usar variables globales y pasar variables a las funciones como argumentos y devolverlas como resultados en lugar de eso.