Python es un lenguaje de alto nivel cercano al lenguaje natural, interpretado, multiplataforma, scripting y de propósito general. Precisamente, es su cercania con el lenguaje natural lo que facilita su aprendizaje. En este tutorial se realiza un recorrido por los principales tópicos de dicho lenguaje.
Introducción
Variables y Operadores
Las variables y los operadores son dos conceptos fundamentales en la programación en Python. Las variables se utilizan para almacenar datos, y los operadores se utilizan para realizar operaciones con datos.
Variables
En Python, una variable es un espacio de almacenamiento que tiene
un nombre identificador y contiene un valor o referencia a un
objeto. Al asignar un valor a una variable, le das un nombre
descriptivo que luego puedes utilizar para referenciar y manipular
ese valor. La asignación de variables en Python se realiza
mediante el operador de asignación =.
A continuación muestro un ejemplo:
# Asignación de variables
nombre = "John"
edad = 25
altura = 1.75
es_estudiante = True
Operadores
Python incluye varios tipos de operadores que permiten realizar operaciones en variables y valores. Aquí hay algunos de los operadores más comunes:
-
Operadores Aritméticos
Los operadores aritméticos más comunes son
- Suma: +
- Resta: -
- Multiplicación: *
- División: /
- Potenciación: **
-
Operadores Lógicos
Los operadores lógicos más comunes son:
- AND:
and
- OR:
or
- NOT:
not
- AND:
-
Operadores de Comparación
Los operadores de comparación más comunes son:
- Igual:
==
- Distinto:
!=
- Mayor que:
>
- Menor que:
<
- Mayor o igual que:
>=
- Menor o igual que:
<=
- Igual:
-
Operadores de Asignación
Los operadores de asignación más comunes son:
- Suma:
+=
- Resta:
-=
- Multiplicación:
*=
- División:
/=
- Módulo:
%=
- Potenciación:
**=
- Suma:
Estructuras de Datos
Las estructuras de datos son contenedores que almacenan datos. Python proporciona una variedad de estructuras de datos, como listas, tuplas, conjuntos y diccionarios.
Listas
Una lista es una estructura de datos que puede almacenar una secuencia de elementos. Los elementos de una lista pueden ser de cualquier tipo de dato, incluidos números, cadenas, objetos y otras listas. Para crear una lista, se usa la corchetes []. Por ejemplo, para crear una lista que almacenará los números 1, 2 y 3, se usaría el siguiente código:
numeros = [1, 2, 3]
Tuplas
Una tupla es una estructura de datos similar a una lista, pero los elementos de una tupla son inmutables. Esto significa que los elementos de una tupla no se pueden modificar una vez que se han asignado. Para crear una tupla, se usa la sintaxis ( y ). Por ejemplo, para crear una tupla que almacenará los números 1, 2 y 3, se usaría el siguiente código:
numeros = (1, 2, 3)
Conjuntos
Un conjunto es una estructura de datos que almacena una colección de elementos únicos. Los elementos de un conjunto no están ordenados y no tienen índices. Para crear un conjunto, se usa la sintaxis {}. Por ejemplo, para crear un conjunto que almacenará los números 1, 2 y 3, se usaría el siguiente código:
numeros = {1, 2, 3}
Diccionarios
Un diccionario es una estructura de datos que permite almacenar y organizar datos de manera eficiente. Se trata de una colección no ordenada de pares clave-valor, donde cada clave debe ser única. Los diccionarios son conocidos también como "mapas" o "tablas hash" en otros lenguajes de programación. Un diccionario en Python se define utilizando llaves {} y tiene la siguiente estructura básica:
personas = { "Juan": 20, "María": 25 }
Control de Flujo
El control de flujo en Python es el proceso de controlar el orden en que se ejecutan las instrucciones de un programa. Se utiliza para determinar qué instrucciones se ejecutan, cuándo se ejecutan y cuántas veces se ejecutan.
Sentencias condicionales
Las sentencias condicionales se utilizan para controlar el flujo
del programa en función de una condición. Las sentencias
condicionales más comunes en Python son if
,
elif
y else
.
Bucles
Los bucles se utilizan para ejecutar un bloque de instrucciones
repetidamente. Los bucles más comunes en Python son
while
, for
y se utiliza la palabra
break
para interrumpir la ejecución del loop y la
palabra clave continue
para saltar de la actual
iteración a la siguiente.
Funciones
Una función es un bloque de código reutilizable que se puede llamar desde cualquier parte del programa. Las funciones se utilizan para dividir un programa en tareas más pequeñas y manejables, y para hacer que el código sea más fácil de leer y mantener.
Para definir una función en Python, se utiliza la palabra clave
def
seguida del nombre de la función, los parámetros
de entrada y el cuerpo de la función. El cuerpo de la función es
un bloque de código que se ejecutará cuando se llame a la función.
El siguiente código define una función llamada sum() que suma dos números:
def sum(a, b):
return a + b
La misma función anterior se puede crear utilizando una función anónima lambda y asignarla a una variable:
sum=lambda a, b: a + b
Programación Orientada a Objetos (POO)
La Programación Orientada a Objetos (POO) es un paradigma de
programación que organiza el código en torno a objetos. Los
objetos son entidades que contienen datos (llamados atributos) y
métodos (funciones que se aplican a una instancia de la clase).
Los datos son información que el objeto almacena, y los métodos
son acciones que el objeto puede realizar.
En Python, la POO se implementa mediante clases. Las clases son
plantillas que se utilizan para crear objetos. Las clases definen
los datos y los métodos que tendrá un objeto.
El siguiente código define una clase llamada Mascota
:
class Mascota:
def __init__(self, nombre, especie):
self.nombre = nombre
self.especie = especie
def presentarse(self):
return f"Soy {self.nombre}, una
{self.especie}."
mi_mascota = Mascota("Firulais", "perro")
print(mi_mascota.presentarse())
Decoradores
Los decoradores son funciones que se utilizan para modificar el comportamiento de otras funciones. Los decoradores se pueden utilizar para agregar funcionalidad, realizar comprobaciones de seguridad o registrar información sobre la ejecución de una función.
Los decoradores se definen usando la sintaxis siguiente:
@decorador_funcion
def funcion_a_decorar():
pass
En esta sintaxis, decorador_funcion
es la función
decoradora, y funcion_a_decorar
es la función que se
va a decorar. La función decoradora se ejecuta antes de que se
ejecute la función a decorar. La función decoradora puede devolver
la función a decorar, o puede devolver una función completamente
nueva.
def imprimir_nombre_funcion(funcion):
def wrapper(*args, **kwargs):
print(funcion.__name__)
return funcion(*args, **kwargs)
return wrapper
Este decorador se puede utilizar de la siguiente manera:
@imprimir_nombre_funcion
def saludar(nombre):
print("Hola, {}!".format(nombre))
Iteradores y Generadores
Los iteradores y generadores son conceptos relacionados que permiten trabajar eficientemente con secuencias de datos, especialmente cuando se trata de conjuntos de datos grandes o cuando queremos generar valores sobre la marcha sin almacenarlos todos en la memoria.
Iteradores:
Un iterador es un objeto que implementa los métodos
__iter__()
y __next__()
. El método
__iter__()
devuelve el propio objeto iterador, y el
método __next__()
proporciona el siguiente elemento
de la secuencia.
El siguiente es un ejemplo de uso:
class Contador:
def __init__(self, limite):
self.limite = limite
self.valor_actual = 0
def __iter__(self):
return self
def __next__(self):
if self.valor_actual <
self.limite:
resultado =
self.valor_actual
self.valor_actual += 1
return resultado
else:
raise StopIteration
# Uso del iterador
contador_iterador = Contador(5)
for numero in contador_iterador:
print(numero)
Generadores:
Los generadores son una forma más sencilla y cómoda de crear
iteradores. Se definen mediante funciones que contienen la palabra
clave yield. Cuando se llama al generador, la
ejecución se pausa en la instrucción yield, y el
valor se devuelve al llamante. La próxima vez que se llama al
generador, la ejecución se reanuda justo después del
yield, manteniendo el estado interno.
El siguiente es un ejemplo de uso:
def generador_pares(n):
for i in range(0, n, 2):
yield i
# Uso del generador
for num in generador_pares(6):
print(num)
En este ejemplo, el generador
generador_pares produce números pares hasta el
límite n. Cada vez que se itera sobre el generador, la ejecución
se pausa en el yield
y se reanuda cuando se solicita
el siguiente valor.
Módulos y Paquetes
Los módulos y paquetes son mecanismos que permiten organizar y estructurar el código de manera más eficiente, facilitando la reutilización y el mantenimiento del código.
Módulos:
Un módulo en Python es simplemente un archivo que contiene código
Python, ya sea funciones, clases o variables. Un módulo puede ser
importado en otro script o programa, permitiendo así la
reutilización de código.
Ejemplo de Módulo:
Supongamos que tenemos un archivo llamado
operaciones.py con el siguiente contenido:
# operaciones.py
def suma(a, b):
return a + b
def resta(a, b):
return a - b
Este archivo se puede considerar un módulo. Para usar las funciones definidas en este módulo en otro archivo, simplemente lo importamos:
# otro_script.py
import operaciones
resultado_suma = operaciones.suma(5, 3)
resultado_resta = operaciones.resta(10, 4)
print("Suma:", resultado_suma)
print("Resta:", resultado_resta)
Paquetes
Un paquete en Python es una forma de organizar múltiples módulos
relacionados en un directorio. Un paquete debe contener un archivo
especial llamado __init__.py para que Python lo
reconozca como un paquete.
Ejemplo de Paquete:
Supongamos que tenemos una estructura de directorios como esta:
mi_paquete/
|-- __init__.py
|-- operaciones/
|-|-- __init__.py
|-|-- suma.py
|-|-- resta.py
|-- otro_script.py
Los archivos suma.py y resta.py contienen las funciones de mi_suma y mi_resta, respectivamente. El contenido de __init__.py (tanto en mi_paquete como en operaciones) puede ser un archivo vacío o contener código que se ejecuta cuando el paquete o módulo se importa.
# otro_script.py
from mi_paquete.operaciones import suma, resta
resultado_suma = suma.mi_suma(5, 3)
resultado_resta = resta.mi_resta(10, 4)
print("Suma:", resultado_suma)
print("Resta:", resultado_resta)
También puede ser realizado de la siguiente manera:
# otro_script.py
from mi_paquete.operaciones.suma import mi_suma
from mi_paquete.operaciones.resta import mi_resta
resultado_suma = mi_suma(5, 3)
resultado_resta = mi_resta(10, 4)
print("Suma:", resultado_suma)
print("Resta:", resultado_resta)
Los módulos y paquetes son esenciales para estructurar proyectos más grandes y facilitar la reutilización del código en Python.
Manejo de Excepciones
El manejo de excepciones en Python se refiere a la práctica de
gestionar y responder a situaciones excepcionales o errores
durante la ejecución de un programa. Las excepciones son eventos
que pueden ocurrir durante la ejecución y que pueden interrumpir
el flujo normal del programa si no se manejan adecuadamente. El
manejo de excepciones permite a los programadores anticipar y
gestionar estas situaciones excepcionales, evitando que el
programa se bloquee o produzca resultados incorrectos.
En Python, el manejo de excepciones se realiza mediante bloques
try, except,
else y finally. La estructura
básica es la siguiente:
try:
# Código que puede generar una excepción
resultado = dividir(10, 0)
except ZeroDivisionError:
# Manejo específico para la excepción
ZeroDivisionError
print("Error: No se puede dividir por
cero.")
except Exception as e:
# Manejo genérico para otras
excepciones
print(f"Error inesperado: {e}")
else:
# Se ejecuta si no hay excepciones
print("La división se realizó con
éxito.")
finally:
# Se ejecuta siempre,
independientemente de si se produjo una excepción o no
print("Este bloque se ejecuta
siempre.")
En este ejemplo se tiene lo siguiente:
- El código dentro del bloque try es susceptible a lanzar una excepción.
- Los bloques except especifican cómo manejar excepciones particulares. En este caso, se maneja la excepción ZeroDivisionError y, de manera más genérica, Exception.
- El bloque else se ejecuta si no se produce ninguna excepción en el bloque try.
- El bloque finally se ejecuta siempre, independientemente de si se produjo una excepción o no. Es útil para realizar acciones de limpieza o liberación de recursos.
Expresiones Regulares
Las expresiones regulares (también conocidas como regex o regexp)
son patrones de búsqueda de texto que se utilizan para realizar
operaciones de búsqueda y manipulación en cadenas de texto. En
Python, las expresiones regulares se implementan a través del
módulo re
, que proporciona funciones para trabajar
con estas expresiones.
Las expresiones regulares son extremadamente poderosas y
flexibles, permitiendo buscar patrones específicos, realizar
sustituciones, validar formatos y más.
Sintaxis Básica de Expresiones Regulares en Python:
-
Raw Strings (cadenas sin procesar): En Python, se recomienda utilizar cadenas sin procesar (precedidas por r) al trabajar con expresiones regulares, ya que evitan la necesidad de duplicar barras invertidas (\) para escapar caracteres especiales.
patron = r"\d{3}-\d{2}-\d{4}"
-
Metacaracteres Comunes:
- .: Coincide con cualquier carácter excepto una nueva línea.
- ^: Coincide con el inicio de una cadena.
- $: Coincide con el final de una cadena.
Este es un ejemplo de uso de ^:
import re
texto = "Hola, mundo!"
# Buscar la palabra "Hola" al principio de la cadena
resultado = re.search(r"^Hola", texto) -
Cuantificadores:
- * : Coincide con 0 o más repeticiones del carácter anterior.
- + : Coincide con 1 o más repeticiones del carácter anterior.
- ? : Coincide con 0 o 1 repetición del carácter anterior.
- {m,n} : Coincide con entre m y n repeticiones del carácter anterior.
-
Clases de Caracteres:
- [...] : Coincide con cualquier carácter dentro de los corchetes.
- [^...] : Coincide con cualquier carácter que no esté dentro de los corchetes.
Estos son solo algunos ejemplos básicos. Las expresiones regulares
pueden volverse bastante complejas y son una herramienta poderosa
para la manipulación de cadenas de texto. La biblioteca
re
en Python proporciona varias funciones, como
search
, match
, findall
,
sub
, entre otras, para trabajar con expresiones
regulares.
Manipulación de Archivos
La manipulación de archivos en Python se refiere a la capacidad
del lenguaje para realizar operaciones de lectura, escritura y
manipulación de archivos en el sistema de archivos del sistema
operativo. Python posee la función open
para
interactuar con archivos de texto y binarios.
Ejemplos de Manipulación de Archivos:
-
Lectura de un Archivo de Texto:
# Abrir un archivo en modo de lectura
with open("archivo.txt", "r") as archivo:
# Leer todo el contenido del archivo
contenido = archivo.read()
print(contenido)
# O leer línea por línea
archivo.seek(0) # Reiniciar el puntero del archivo al principio
lineas = archivo.readlines()
for linea in lineas:
print(linea.strip()) # Eliminar caracteres de nueva línea al final
-
Escritura en un Archivo de Texto:
# Abrir un archivo en modo de escritura
with open("nuevo_archivo.txt", "w") as archivo:
# Escribir contenido en el archivo
archivo.write("Hola, este es un nuevo archivo.\n")
archivo.write("Línea 2: Contenido adicional.") -
Manipulación de Archivos Binarios:
# Leer y escribir archivos binarios
with open("imagen.jpg", "rb") as archivo_entrada:
datos_binarios = archivo_entrada.read()
with open("copia_imagen.jpg", "wb") as archivo_salida:
archivo_salida.write(datos_binarios)
-
Uso de la Instrucción
with
para Garantizar el Cierre del Archivo:La instrucción
with
asegura que el archivo se cierre adecuadamente después de que se complete el bloque de código. Esto es útil para prevenir posibles problemas de manejo de archivos y para liberar recursos.with open("archivo.txt", "r") as archivo:
# Realizar operaciones de lectura
contenido = archivo.read()
print(contenido)
# El archivo se cerrará automáticamente al salir del bloque 'with'
Estos son solo ejemplos básicos. Además de los modos de lectura y
escritura ("r" ,"w" ), existen
otros modos como "a" (para añadir al final del
archivo) y "b" (para modo binario). También
puedes utilizar la biblioteca os
para operaciones más
avanzadas en archivos y directorios.
Recordar manejar excepciones, como FileNotFoundError al abrir
archivos, para garantizar la robustez del código.
Trabajo con API REST
El trabajo con API REST en Python implica interactuar con
servicios web que siguen los principios de arquitectura REST
(Transferencia de Estado Representacional). Las API REST utilizan
operaciones HTTP estándar (GET, POST, PUT, DELETE) para realizar
acciones sobre recursos, y los datos se suelen enviar y recibir en
formato JSON.
A continuación, se muestra un ejemplo básico de cómo realizar
solicitudes a una API REST utilizando el módulo
requests en Python.
Ejemplo de Trabajo con API REST:
import requests
# Ejemplo de una API pública (JSONPlaceholder: Fake Online REST
API for Testing and Prototyping)
url = "https://jsonplaceholder.typicode.com/posts/1"
# Realizar una solicitud GET para obtener un recurso
response = requests.get(url)
# Verificar si la solicitud fue exitosa (código de estado
200)
if response.status_code == 200:
# Convertir la respuesta a formato JSON
datos = response.json()
print("Título del post:", datos["title"])
else:
print("Error en la
solicitud:",response.status_code)
En el ejemplo anterior se realiza lo siguiente:
- Se utiliza la biblioteca requests para realizar una solicitud HTTP GET a la API pública JSONPlaceholder.
- Se verifica el código de estado de la respuesta. Un código de estado 200 indica que la solicitud fue exitosa.
- Si la solicitud fue exitosa, se convierten los datos de la respuesta a formato JSON y se imprime el título del post.
Ejemplo de Envío de Datos con una Solicitud POST:
import requests
# Ejemplo de una API pública para crear un nuevo recurso
url = "https://jsonplaceholder.typicode.com/posts"
# Datos a enviar en la solicitud POST
datos_nuevo_post = {
"title": "Nuevo Post",
"body": "Contenido del nuevo post",
"userId": 1
}
# Realizar una solicitud POST para crear un nuevo recurso
response = requests.post(url, json=datos_nuevo_post)
# Verificar si la solicitud fue exitosa (código de estado 201
para creación exitosa)
if response.status_code == 201:
nuevo_post = response.json()
print("Nuevo Post creado. ID:",nuevo_post["id"])
else:
print("Error en la
solicitud:",response.status_code)
En este ejemplo, se realiza una solicitud HTTP POST para crear un
nuevo post en la API JSONPlaceholder enviando datos en formato
JSON.
Estos son ejemplos básicos, y trabajar con API REST puede
involucrar autenticación, manejo de parámetros, paginación y más,
dependiendo de la API específica con la que estés interactuando.