====== Python ======
Lenguaje interpretado, multiparadigma y multiplataforma.
* [[https://www.python.org/|Web oficial]]
Al ser un lenguaje interpretado, el elemento que se encarga de ejecutar un programa Python (el intérprete) ejecuta cada sentencia una a una, empezando desde el comienzo del fichero que contiene el código Python.
Páginas relacionadas:
* [[informatica:programacion:python:poo|Python: Programación Orientada a Objetos]]
* [[informatica:programacion:python:web_scraping|Python: Web Scraping]]
* [[informatica:programacion:python:fechas|Python: Fechas]]
* [[informatica:programacion:python:ficheros|Python: Ficheros]]
* [[informatica:programacion:python:mail|Python: Mail]]
* [[informatica:programacion:python:automatizacion_gui|Python: Automatización GUI]]
* [[informatica:programacion:python:ftp|Python: FTP]]
* [[informatica:programacion:python:graficas|Python: Gráficas]]
* [[informatica:programacion:python:matematicas|Python: Matemáticas]]
* [[informatica:programacion:python:bases_de_datos|Python: Bases de Datos]]
* [[informatica:programacion:python:sistema_ficheros|Python: Sistema de ficheros]]
* [[informatica:programacion:python:depuracion|Python: Depuración]]
===== Características =====
* **Interpretado**: El código Python se ejecuta directamente por el intérprete, sin necesidad de compilarlo previamente. Esto lo hace más rápido de desarrollar y depurar.
* **Multiparadigma**: Python admite diferentes paradigmas de programación, como la programación imperativa, la programación orientada a objetos y la programación funcional. Esto lo hace versátil y adaptable a diferentes necesidades.
* **Multiplataforma**: Python se puede ejecutar en una amplia gama de plataformas, incluyendo Windows, macOS, Linux y Android.
* **Propósito general**: Python se puede utilizar para una amplia gama de aplicaciones, incluyendo desarrollo web, ciencia de datos, inteligencia artificial y machine learning.
* **Tipado dinámico**: Python es un lenguaje de tipado dinámico, lo que significa que los tipos de datos no se declaran explícitamente.
Python tiene una comunidad activa de desarrolladores que proporcionan soporte y recursos.
===== Instalación =====
==== Linux ====
Debian 10 viene con Python 2 y Python 3.
En Arch Linux:
pacman -S python
El intérprete oficial de Python es **cpython**
También se puede optar por soluciones como [[https://www.anaconda.com/|Anaconda]] que viene con bibliotecas y editores. Para Windows, existe [[https://winpython.github.io/|WinPytyon]] que también incluye paquetes y editores, pero es portable.
Para saber la versión que tenemos instalada de Python:
python -V
Ejemplo de salida:
Python 3.8.6
===== Ejecución =====
Como Python es un lenguaje interpretado, para poder ejecutar los programas que escribamos en este lenguaje, debemos hacerlo a través del intérprete:
python script.py
Los scripts de Python tienen la extensión ''.py''
==== Linux ====
Si queremos ejecutarlo como un script, tenemos que añadir como primera línea en los scripts:
#! /usr/bin/env python
Esto indicará al intérprete de comandos dónde debe buscar el intérprete de Python para ejecutar ese script.
Finalmente, le daremos permisos de ejecución:
chmod +x script.py
Y podremos lanzarlo de la siguiente manera:
./script.py
===== Gestión de paquetes =====
**pip** es el instalador oficial de paquetes Python.
En Arch Linux se instala a través del paquete ''python-pip''. En Debian con ''python3-pip''.
===== Todo es un objeto =====
En Python todo es un objeto:
* ''1234''
* ''3.14159''
* ''%%"%%Hola%%"%%''
* ''[1, 2, 3, 4, 5]''
* ''{%%"%%CA%%"%%: %%"%%California%%"%%, %%"%%MA%%"%%: %%"%%Massachusetts%%"%%}}''
Todos ellos son objetos y cada objeto tiene:
* Un tipo
* Una representación de la información (primitiva o compuesta)
* Un conjunto de funciones (métodos) para interactuar con el objeto.
Un objeto es la "instancia" de un tipo:
* ''1234'' es una instancia de un ''int''
* ''%%"%%hola%%"%%'' es una instancia de un ''string''
Incluso las funciones son también objetos en Python.
* Podemos crear nuevos objetos
* Podemos manipular objetos
* Podemos destruir objetos (podemos hacerlo explícitamente o Python también dispone de un recolector de basura)
Un objeto es una abstracción de la información que captura:
* La representación interna (a través de los atributos)
* Una interfaz para interactuar con el objeto (a través de métodos). Define comportamientos, pero oculta la implementación.
===== Hola, mundo =====
Si creamos un fichero con el contenido:
print("Hola, mundo!")
Y lo guardamos como ''hola-mundo.py'', podemos ejecutarlo con
python hola-mundo.py
Python es un lenguaje interpretado así que para ejecutar los programas hechos en este lenguaje es necesario lanzarlos con un intérprete que es el que se encargará de generar un bytecode que finalmente ejecutará la máquina virtual para hacer la traducción final a código máquina.
===== Imprimir por pantalla =====
==== Método format ====
El objeto String contiene el método ''format()'' que es una de las mejores maneras de formatear cadenas de caracteres en Python:
nombre = "Pepito"
apellido = "Grillo"
print("Me llamo {a}, {n} {a}".format(a=apellido, n=nombre))
# "Me llamo Grillo, Pepito Grillo"
===== Saludar =====
Otro ejemplo típico es pedir el nombre y responder con un saludo
nombre = input("Cómo te llamas? ")
print("Hola, " + nombre)
Podemos utilizar //placeholders// o marcadores de posición:
nombre = input("Cómo te llamas? ")
print("Hola, %s" % nombre)
Con ''%s'' indicamos que en ese lugar va a ir el contenido de una variable tipo string. Después le decimos qué variable ocupará ese lugar.
Si queremos imprimir más de una variable:
num1 = 10
num2 = 30
sum = num1 + num2
print("La suma de %s + %s es %s", % (num1, num2, sum))
===== Comentarios =====
Texto que el intérprete de Python ignorará. En Python los comentarios comienzan con ''#''
# Esto es un comentario
# Este comentario tiene
# varias
# líneas
print(1 + 1) # Esto también es un comentario
Python no tiene una forma de delimitar comentarios multilínea, pero se puede utilizar una cadena de caracteres (string) multilínea:
"""
Este texto puede ser considerado
un comentario mientras no esté
asignado a una variable
"""
===== Tipos de datos =====
Los tipos de datos son una categoría de valores. Cada valor pertenece a un único tipo de dato.
En Python todo es un objeto.
==== Números enteros ====
* 5
* 10
* -23
* 0
==== Números decimales ====
* 3.14
* 9.99
* -113.1268
==== Cadenas de caracteres ====
Son trozos de texto, una secuencia de caracteres. También conocido como //strings//. Se indican entre comillas simples (''%%'%%''), dobles (''%%"%%'') o triple comillas dobles (''%%"""%%'').
* ''%%"%%hola%%"%%''
* ''%%'%%hola%%'%%''
* '3'
* ''%%"%%%%"%%'' (string vacío)
'3' (string) es distinto de 3 (número entero)
Los strings en Python son tipos de datos **inmutables**, no pueden cambiar.
==== Boolean ====
Valores lógicos, indican si algo es verdadero o falso.
* ''False''
* ''True''
Los tipos de datos boolean deben comenzar con mayúsculas
==== None ====
Es un tipo de dato especial que se usa para representar nada o la ausencia de un valor. Sería algo parecido a //null// en otros lenguajes.
* ''None''
===== Casting (conversiones) =====
//Cast//, en el mundo de la programación, se podría traducir como convertir o modelar, es decir, partir de una cosa y obtener otra diferente. En Python contamos con varias funciones para convertir ciertos tipos de datos en otros:
* ''int()'': crea un número entero a partir de un literal entero, decimal o un string que representa un número.
* ''float()'': crea un número decimal (en coma flotante) a partir de un literal entero, decimal o string que representa un número
* ''str()'': crea un string desde una variedad de tipos de datos (cadenas, enteros, decimales...)
===== Operadores =====
Símbolos que realizan ciertas operaciones sobre los objetos.
==== Ariméticos ====
* ''+'': suma
* ''-'': resta
* ''*'': multiplicación
* ''/'': división
* ''%%**%%'': potencia
* ''%%//%%'': división entera. Descarta la parte decimal.
* ''%'': módulo. Resto de la división.
Siempre que hagamos una división, obtendremos un número decimal, aunque la división sea exacta. Tendríamos que hacer una conversión del tipo de dato para que fuese entero.
Precedencia, orden en que los operadores son evaluados (prioridad de las operaciones).
PEMDAS es un mnemotécnico para recordar el orden de las operaciones:
* **P**aréntesis
* **E**xponentes
* **M**ultiplicación
* **D**ivisión
* **A**dición (suma)
* **S**ustracción (resta)
==== Concatenación ====
Unión de cadenas de caracteres. Se utiliza el signo más (''+''):
"hola" + " mundo"
# Resultado:
# "hola mundo"
Si queremos repetir una cadena cierto número de veces, utilizamos el asterisco (''*'') para indicar las veces que queremos repetir la cadena:
"hola" * 5
# Resultado:
# "holaholaholaholahola"
==== Lógicos y comparación ====
* ''=='': igualdad
* ''>'': mayor que
* ''<'': menor que
* ''>='': mayor o igual que
* ''%%<=%%'': menor o igual que
* ''!='': distinto
* ''and''
* ''or''
* ''not''
Tabla de verdad del operador ''and'':
^ Expresión ^ Se evalúa a ^
| True and True | True |
| True and False | False |
| False and True | False |
| False and False | False |
Tabla de verdad del operador ''or'':
^ Expresión ^ Se evalúa a ^
| True and True | True |
| True and False | True |
| False and True | True |
| False and False | False |
Tabla de verdad del operador ''not'':
^ Expresión ^ Se evalúa a ^
| not True | False |
| not False | True |
===== Variables =====
Nombre que le damos a un objeto en Python.
==== Asignación ====
Para crear una variable utilizamos el símbol ''='' como operador de asignación:
nombre = "Pepito"
Como en Python todo es un objeto, al crear una variable, estamos haciendo una referencia a un objeto y al asignarle un valor, indicamos el valor que contiene dicho objeto. ''a = %%"%%hola%%"%%'' y ''b = %%"%%hola%%"%%'' son dos referencias al mismo objeto.
Reglas de nomenclatura:
* Deben empezar con una letra o guión bajo (''_'')
* Pueden contener letras, números y guiones bajos
* No se pueden utilizar caracteres especiales o palabras reservadas.
Para ver un listado de las palabras reservadas, podemos utilizar ''kwlist'' del módulo ''keyword'':
''print(keyword.kwlist)''
Python también permite hacer asignaciones múltiples a la vez:
a, b, c = 10, 20, 30
===== Control de flujo =====
Modifican el flujo de ejecución del programa, deciden qué instrucciones se ejecutarán bajo ciertas circunstancias.
==== Condicionales ====
if (condicion):
codigo
else:
codigo
Es muy importante respetar la sangría para indicar que estamos dentro de una estructura de control o función y saber a qué corresponde cada bloque de código.
if (condicion):
codigo
elif (condicion):
codigo
elif (condicion):
codigo
==== Bucles ====
Repiten un mismo código mientras se cumple una condición.
=== While ===
while (condicion):
codigo
Si queremos forzar la salida de un bucle, incluimos la palabra reservada ''break'':
while (condicion):
codigo
break
Si provocamos un bucle infinito (nunca termina su ejecución), podemos forzar la parada con la combinación de teclas ''Ctrl'' + ''c''
Si queremos forzar a que salte a la siguiente repetición del código, usaremos la palabra reservada ''continue'':
while (condicion):
codigo
continue
=== For ===
La diferencia con las sentencias while es que en los bucles for especificamos el número de veces que se repetirá el código.
for i in range(5):
print("Hola")
La función ''range'' genera números. Para el ejemplo, genera 5 números, números del 0 al 4
===== Funciones del sistema =====
Las funciones son bloques de código, una secuencia de instrucciones que permiten obtener un resultado consistente.
Python incluye ciertas funciones para facilitar ciertas operaciones o cálculos.
==== len ====
Cuenta los caracteres que tiene una cadena, lista, mapa o tupla.
len("Hola, caracola")
# Resultado:
# 14
==== str ====
Convierte un número en un string:
str(3.14)
# Resultado:
# '3.14'
==== int ====
Convierte un valor a número entero.
==== float ====
Convierte un valor a número decimal.
==== type ====
Indica el tipo de dato de cierto valor o variable
type(5)
# Resultado:
# int
==== dir ====
Devuelve todos los atributos y métodos disponibles en un objeto.
saludo = "hola"
dir(saludo)
# Resultado:
# ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isascii', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
==== help ====
Devuelve una descripción de lo que realiza una función de Python.
help(max)
# Help on built-in function max in module builtins:
# max(...)
# max(iterable, *[, default=obj, key=func]) -> value
# max(arg1, arg2, *args, *[, key=func]) -> value
# With a single iterable argument, return its biggest item. The
# default keyword-only argument specifies an object to return if
# the provided iterable is empty.
# With two or more arguments, return the largest argument.
==== eval ====
Evalúa
eval ("print('hola')")
# hola
Es útil cuando queramos que se ejecute algún comando introducido directamente por el usuario y ver su resultado.
==== sorted ====
Devuelve resultados ordenados
sorted(["Pepito", "Manolito", "Alejandro"])
# Resultado
# ['Alejandro', 'Manolito', 'Pepito']
==== max ====
Devuelve el valor máximo
==== min ====
Devuelve el valor mínimo
==== sum ====
Devuelve la suma de unos valores.
==== list ====
Convierte en una lista.
==== dict ====
Convierte en un diccionario.
===== Funciones personalizadas =====
Funciones que crea el usuario.
def nombre_funcion(arg1, arg2):
codigo
codigo
codigo
return valor
Los argumentos son los valores de entrada que espera la función.
En Python, al no usar llaves para indicar bloques de código, es importante respetar la sangría del texto para indicar qué está contenido dentro de qué
Ejemplo de función:
def convertir_a_fahrenheit(celsius):
producto = celsius * 1.8
return producto + 32
Y la usaríamos:
convertir_a_fahrenheit(0)
# Resultado:
# 32.0
===== Módulos =====
Si tenemos un script de Python con funciones que nos interesen usar desde otros scripts, podemos importarlo como un módulo de Python:
import os
os.chdir("/directorio/scripts")
# Importamos el script por el nombre del fichero (sin la extensión)
import nombre-script
# Usamos las funciones del script
nombre-script.funcion()
Importante, para que no se ejecuten las funciones del script que vamos a importar, en el script a importar todo lo que no queremos que se ejecute debe ir dentro de:
if __main__ == "__main__":
Si solo queremos importar un método de un módulo:
from math import sqrt
print(sqrt(9))
Si hubiésemos importado todo el módulo:
import math
print(math.sqrt(9))
===== Métodos de cadenas =====
Los métodos son funciones sobre los objetos. En Python vienen definidos varios para las cadenas de caracteres:
trabajo = "Desarrollador"
trabajo.upper()
# Resultado:
# "DESARROLLADOR"
trabajo.lower()
# Resultado:
# "desarrollador"
trabajo.swapcase()
# Resultado:
# "dESARROLLADOR"
# Recordamos que los strings en Python son inmutables
# así que si vemos qué contiene 'trabajo':
# "Desarrollador"
titulo = "los goonies"
titulo.title()
# Resultado
# 'Los Goonies'
texto = " Esto tiene espacios "
texto.strip
# Resultado
# 'Esto tiene espacios'
trabajo.replace("e", 3)
# Resultado
# 'D3sarrollador'
Más métodos de strings:
* ''startswith'': indica si una cadena empieza por cierto(s) caracter(es).
* ''endswith'': indica si una cadena termina por cierto(s) caracter(es).
Otra forma de comprobar si algo está contenido en una cadena, podemos usar el operador ''in'':
"cara" in "hola, caracola"
# Resultado:
# True
===== Métodos numéricos =====
Número entero aleatorio entre un rango (incluye los límites):
import random
print(random.randint(1, 100))
===== Estructuras de datos =====
==== Listas ====
Estructura que contiene una colección ordenada de elementos de cualquier tipo. Es mutable, puede modificarse.
[1, 2, 3, 4, 5]
# Asignación
amigos = ['Fulanito', 'Menganito']
Podemos usar la función ''len'' para saber cuántos elementos tiene la lista.
Añadir elementos:
amigos.append("Zutanito")
Eliminar el último elemento:
amigos.pop()
# Resultado
# 'Zutanito'
Si queremos elegir cierto elemento a eliminar:
amigos.remove("Fulanito")
Para buscar elementos en una lista, se puede utilizar el operador ''in'':
amigos = ['Fulanito', 'Menganito', 'Zutanito']
"Pepito" in amigos
# Resultado:
# False
==== Diccionarios ====
Colección **desordenada** de pares clave-valor. Como una carta de un restaurante donde hay una asociación entre el plato y el valor del mismo.
menu = {
"Filet Mignon": 29.99,
"Pizza": 7.99,
"Hamburguesa": 3.99
}
Para acceder a cierto elemento, usamos su índice que en este caso será la **clave**:
menu['Pizza']
# Resultado:
# 7.99
Podemos añadir más pares a un diccionario ya existente:
menu["Burrito"] = 5.99
O modificar un par existente:
menu["Pizza"] = 10.99
Si queremos eliminar:
menu.pop("Filet Mignon")
Para saber si existe un elemento, utilizamos el operador ''in'':
"Burrito" in menu
# Resultado:
# True
Si queremos hacer la búsqueda por los valores y no por las claves:
5.99 in menu.values()
# Resultado:
# True
==== Tuplas ====
==== Conjuntos ====
===== Índices y cortes (slicing) =====
En Python el conteo empieza en 0. Es decir, que el primer caracter de una cadena de caracteres ocupa la posición 0
heroe = "Spiderman"
heroe[1]
# Resultado
# 'p'
# Último caracter:
heroe[-1]
# Resultado
# 'n'
También funciona con las listas:
heroes = ["Batman", "Spiderman", "Superman", "Daredevil", "Ironman"]
heroes[1]
# Resultado:
# 'Spiderman'
Para poder extraer más elementos de una cadena o una lista:
El primer número indica el índice desde donde queremos hacer la extracción y el segundo representa el índice donde terminaremos la extracción:
heroes[1:3]
# Resultado
# ['Spiderman', 'Superman']
El elemento con el índice de fin no se incluye en la extracción
Cuando la extracción la queremos hacer desde el primer elemento, no tenemos por qué poner ''[0:10]''. El índice de inicio se puede omitir: ''[:10]''
Lo mismo sucede con el índice final cuando queremos llegar hasta el final: ''[2:]''
===== Entrada por teclado =====
Si queremos que el programa obtenga algo del usuario mediante el teclado, usaremos la función ''input()'':
print("Cómo te llamas?")
# El programa se quedará a la espera de que el usuario introduzca
# algún valor por teclado y pulse Enter
nombre = input()
print("Encantado de conocerte, " + nombre)
===== Iterables =====
Los iterables son objetos sobre los que podemos iterar, es decir, recorrer.
==== Secuencias ====
Son iterables con acceso aleatorio, como las tuplas y las listas.
colores = ['rojo', 'verde', 'azul']
for item in colores:
print(item)
==== Asociaciones (mappings) ====
Diccionarios
==== Generadores ====
Los generadores son una forma útil de construir iteradores. A tener en cuenta:
* Los valores se generan a demanda
* Los valores no están en memoria
* Solo se puede iterar una vez
* No hay acceso aleatorio
def mi_range(n):
num = 0
while num < n:
yield num
num += 1
x = mi_range(5)
En este punto ''x'' es ''''
Para recorrerlo:
for item in x:
print(item)
Una vez recorrido, el iterable no puede ser recorrido de nuevo
===== List comprehensions =====
Una //comprehension// es un tipo de construcción que permite crear secuencias a partir de otras secuencias. Normalmente nos referiremos a las listas.
cuadrados = []
for x in range(100):
cuadrados.append(x*x)
Utilizando la comprensión de listas, podríamos hacerlo de la siguiente manera:
cuadrados = [x*x for x in range(100)]
También se puede usar la //comprensión// con diccionarios y objetos iterables.
==== map, reduce y filter ====
Es una forma de lidiar con secuencias utilizando la programación funcional.
Ejemplo con ''map'':
def f(x):
return x*x
numeros = range(10)
# cuadrados = (f(x) for x in numbers)
cuadrados = map(f, numeros)
Ejemplo con ''reduce'':
add_them(a, b):
return a + b
from functools import reduce
seq = [1, 2, 3, 4]
results = reduce(add_them, seq)
# 10
Función ''filter'':
def es_par(x):
return x % 2 == 0
seq = range(10)
numeros_pares = filter(es_par, seq)
# resultado: [0, 2, 4, 6, 8]
===== Manejo de errores =====
==== Excepciones ====
Las excepciones son errores.
* [[https://docs.python.org/3/library/exceptions.html|Built-in Exceptions]]
Sentencias ''try'' y ''except''.
Cualquier error que suceda dentro de un bloque ''try'', hará que se ejecute el código que se indique en el bloque ''except''. Este código manejará el error o mostrará un mensaje al usuario y el programa podrá seguir en ejecución o finalizar correctamente.
print("Vamos a dividir")
print("Dame un dividendo:")
dividendo = int(input())
print("Dame un divisor:")
divisor = int(input())
try:
resultado = dividendo / divisor
print("Resultado: " + resultado)
except ZeroDivisionError:
print("Error: no se puede dividir entre 0")
En la línea del ''except'' indicamos el error que debe capturar el programa para indicar qué hacer. Si no ponemos nada, solo ''except'', se ejecutará esa línea con cualquier error que produzca el programa.
Se pueden añadir tantos bloques ''except'' como excepciones se quieran controlar
También podemos utilizarlo para la validación de datos:
print("Cuántos años tienes?")
edad = input()
try:
if int(edad) >= 18:
print("Eres mayor de edad")
else:
print("Eres menor")
except ValueError:
print("No has introducido un número")
Para generar excepciones utilizamos la palabra reservada ''raise'':
raise Exception("Este es un mensaje de error")
Existe también la estructura con ''else'' y/o ''finally'':
def manejoExcepciones():
try:
a = 10
b = 20
c = 0
d = (a + b) / c
print(d)
except:
print("Estoy en el bloque de las excepciones")
else:
print("Como no ha habido excepciones, me imprimo yo")
finally:
print("Yo me imprimo siempre")
==== Registro (logging) ====
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.debug("Inicio")
def factorial(n):
logging.debug("Calculando factorial(%s)" % (n))
total = 1
for i in range(1, n + 1):
total *= i
logging.debug("Valor devuelto: %s" % (total))
return total
print(factorial(5))
logging.debug("Fin")
Ejemplo de salida:
2020-11-05 13:18:59,752 - DEBUG - Inicio
2020-11-05 13:18:59,755 - DEBUG - Calculando factorial(5)
2020-11-05 13:18:59,757 - DEBUG - Valor devuelto: 1
2020-11-05 13:18:59,759 - DEBUG - Valor devuelto: 2
2020-11-05 13:18:59,761 - DEBUG - Valor devuelto: 6
2020-11-05 13:18:59,762 - DEBUG - Valor devuelto: 24
2020-11-05 13:18:59,764 - DEBUG - Valor devuelto: 120
2020-11-05 13:18:59,765 - DEBUG - Fin
120
Es recomendable no usar ''print()'' para la depuración de un programa ya que cuando hayamos terminado, es mucho más tedioso eliminar esos mensajes.
Si queremos eliminar los mensajes de log, añadimos la siguiente línea al principio:
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
logging.disable(logging.CRITICAL)
Los niveles de log:
* debug (el más bajo)
* info
* warning
* error
* critical (el más alto)
Se usarían en Python de la siguiente manera:
* ''logging.DEBUG''
* ''logging.INFO''
* ''logging.WARNING''
* ''logging.ERROR''
* ''logging.CRITICAL''
Si queremos que los logs vayan a un fichero, añadimos el argumento ''filename'':
import logging
logging.basicConfig(filename="programa-log", level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
===== Ejecución en línea de comandos =====
Hay dos maneras de ejecutar los scripts de Python desde la línea de comandos:
Ejecutando el intérprete de Python sobre el script en cuestión:
python programa.py
Ejecutando el script de Python directamente:
./programa.py
Para este último método, el programa Python debe tener una primera línea que indique la ruta del intérprete. Por ejemplo, en Linux:
#! /usr/bin/env python
A la combinación de los caracteres ''#!'' se le conoce como //shebang//
Además, el script debe ser marcado como ejecutable:
chmod +x programa.py
==== Argumentos ====
Para capturar las opciones/argumentos que le pasamos al script que lanzamos desde línea de comandos:
import sys
# Lista de opciones que pasamos por pantalla
# El primer elemento es el nombre del script
sys.argv
===== Ficheros =====
==== Rutas ====
Las rutas en Windows tienen una barra invertida (''\''). Esto confunde al intérprete porque es el caracter que se usa en Python para las secuencias de escape. Si vamos a usar rutas de Windows, tenemos dos opciones:
* Escapar la barra invertida: ''%%'%%C:\Windows\%%'%%'' sería ''%%'%%C:\\Windows\\%%'%%''
* Indicar que la cadena debe ser tratada tal cual: ''%%'%%C:\Windows\%%'%%'' sería ''r'C:\windows\%%'%%''
Podemos utilizar el módulo ''os'' para lidiar con las rutas:
import os
os.path.join('ruta', 'al', 'fichero.ext')
# Resultado en Windows:
# 'ruta\\al\\fichero.ext'
# Resultado en Linux:
# 'ruta/al/fichero.ext'
Para ver el separador que se está usando:
os.sep
# Resultado en Windows:
# '\\'
# Resultado en Linux:
# '/'
Para obtener la ruta absoluta al directorio actual (en el que se ejecuta el script):
os.getcwd()
Para cambiar de ruta:
os.chdir("/")
os.getcwd()
# Resultado:
# '/'
Para obtener la ruta absoluta a cierto fichero:
fichero = "foto.jpg"
os.path.abspath("foto.jpg")
# Resultado
# '/home/usuario/foto.jpg'
Obtener el directorio de un fichero:
os.path.dirname("/home/usuario/foto.jpg")
# Resultado:
# '/home/usuario'
Obtener el nombre del fichero a partir de su ruta absoluta:
os.path.basename("/home/usuario/foto.jpg")
# Resultado
# 'foto.jpg'
Comprobar si una ruta existe:
os.path.exists("/home/usuario/foto.jpg")
# Resultado
# True si existe
# False si no existe
Si queremos comprobar si una ruta es un fichero o un directorio:
os.path.isfile("/home/usuario/foto.jpg")
# Resultado
# True
os.path.isdir("/home/usuario/foto.jpg")
# Resultado
# False
==== Tamaño ====
Si queremos saber el tamaño de un fichero:
os.path.getsize("/home/usuario/foto.jpg")
# Resultado (en bytes)
918522
==== Listar ====
Para conocer los ficheros que hay en cierta ruta:
os.listdir("/ruta/")
# Resultado
# Lista con el nombre de los ficheros y directorios que contiene '/ruta'
==== Creación directorios ====
os.makedirs("/ruta/dir1")
Si no existe la ruta al directorio que queremos crear, ''os.makedirs()'' los creará
==== Lectura ====
Para leer el contenido de un fichero de texto:
f = open("/ruta/al/fichero.txt")
# Para mostrar su contenido:
f.read()
# Cerramos:
f.close()
Si queremos leer un fichero línea a línea:
f = open("/ruta/al/fichero.txt")
# Lee el fichero y crea una lista con sus líneas
f.read()
# Cerramos:
f.close()
==== Escritura ====
Para poder escribir en un fichero, tenemos que abrir indicando la manera en que vamos a escribir en él:
f = open("/ruta/al/fichero.txt", "w")
f.write("Hola")
f.close()
f2 = open("/ruta/al/fichero2.txt", "a")
f2.write("Hola")
f2.close()
* ''w'': abre el fichero para ser sobrescrito (se perderá el contenido que hubiese)
* ''a'': abre el fichero para añadir contenido a continuación de lo que ya hubiese
==== Copiar ====
import shutil
shutil.copy("/ruta/fichero.txt", "/ruta/destino/fichero.txt")
Si queremos copiar directorios:
shutil.copytree("/ruta/directorio/", "/ruta/directorio_copia")
==== Mover ====
Para mover o renombrar ficheros:
import shutil
shutil.move("/ruta/fichero.txt", "/ruta/destino/fichero.txt")
==== Eliminar ====
Para borrar un fichero:
os.unlink("/ruta/fichero.txt")
Si queremos borrar un directorio (si está vacío):
os.rmdir("/ruta/directorio")
Si queremos eliminar el directorio y todo lo que contiene:
import shutil
shutil.rmtree("/ruta/directorio/")
Ninguna de estas funciones envía los ficheros eliminados a la papelera. Hay un módulo llamado ''send2trash'' que contiene funciones para enviar a la papelera lo que se borre.
===== Editores =====
* IDLE
* [[https://www.spyder-ide.org/|Spyder]]
* [[https://jupyter.org/|Jupyter Notebook]], Jupyter Lab.
* [[https://www.jetbrains.com/es-es/pycharm/|PyCharm]]
===== Curiosidades =====
El nombre de Python viene del gusto del autor por la serie británica Flying Circus, de los Monty Python.
Si ejecutamos ''import this'' en el intérprete de Python veremos el poema //The Zen of Python//:
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
Python se lanzó en 1991. Es más viejo que Java (1995).
No usa corchetes para delimitar bloques de código. Si hacemos ''from %%__%%future%%__%% import braces'' veremos un curioso "error":
File "", line 1
SyntaxError: not a chance
Usa el [[https://docs.python.org/3.8/faq/design.html#why-does-python-use-indentation-for-grouping-of-statements|sangrado]] (//identation//, en inglés) para delimitar bloques de código.
Las funciones pueden devolver más de un valor.
Los bucles ''for'' y ''while'' pueden contener cláusulas ''else''
No existe la construcción ''switch'' o ''case''. Hay que encadenar ''if'', ''elif'', ''else''.
Permite encadenar comparaciones: ''1 < 2 < 3''
Permite añadir comas finales en listas y tuplas:
a = [0, 1, 2, 3,]
b = ("hola", "adios",]
Permite asignación múltiple:
a, b, c = 10, 1, "hola"
Es muy fácil dar la vuelta a las lista:
reves = nums[::-1]
===== Utilidades =====
==== Servidor web ====
python -m http.server
Se lanzará un servidor web sencillo en el puerto 8000. Podemos modificar el puerto pasándolo como argumento:
python -m http.server 8080
El servidor web servirá los ficheros que estén en el directorio donde se haya lanzado el servidor. Si queremos indicar otro directorio, podemos hacerlo con la opción ''-d'' (o ''%%--%%directory''):
python -m http.server -d /home/tempwin/videos
[[https://docs.python.org/3/library/http.server.html|http.server]] es un módulo disponible por defecto en la versión 3 de Python. Para versiones antiguas, existe el módulo ''SimpleHTTPServer''
===== Entornos virtuales =====
El entorno virtual es un sandbox, una caja que queda aislada del resto del sistema. Sirve para pruebas y luego poder destruir todo sin dejar rastro ni afectar al sistema.
Las explicaciones aquí recogidas están centradas en la instalación de Python para Linux. En Windows los comandos para activar y desactivar el entorno virtual son diferentes.
==== Instalación ====
Para comenzar con los entornos virtuales hay que instalar el módulo ''virtualenv'':
pip install virtualenv
==== Creación ====
Creamos el entorno virtual:
python -m venv /code/python/venv
==== Activación ====
En el directorio ''/code/python/venv'', activamos el entorno:
source /code/python/venv/bin/activate
Veremos el prompt que se añade ''(venv)''.
Para ver los módulos instalados:
pip list
Si ejecutamos esa misma instrucción dentro del entorno virtual recién creado, la lista será mucho menor.
En sistemas Windows, para activar el entorno virtual hay que ejecutar ''venv\Scripts\activate''. Se trata de un script en PowerShell y es posible que debamos cambiar la política de ejecución si nos da error.
==== Desactivación ====
Para desactivar el entorno, desde dentro del proyecto:
deactivate
* [[https://towardsdatascience.com/virtual-environments-104c62d48c54|A Guide to Python’s Virtual Environments]]
En sistemas Windows, para activar el entorno virtual hay que ejecutar venv\Scripts\activate. Se trata de un script en PowerShell y es posible que debamos cambiar la política de ejecución si nos da error.
===== Fichero de requisitos =====
==== Creación ====
Aunque no es más que un fichero de texto que podríamos rellenar manualmente, podemos hacerlo de forma automáticamente mediante:
pip freeze > requirements.txt
Dicho comando muestra una lista de todos los módulos Python instalados con sus versiones.
==== Instalar requisitos ====
pip install -r requirements.txt
===== Recursos =====
* [[https://pypi.org/|The Python Package Index (PyPI)]]: repositorio de software para Python
* [[https://repl.it/|repl.it]]: escribir código online y ejecutarlo.
* [[https://glot.io/|glot.io]]: escribir código online y ejecutarlo.
* [[http://automatetheboringstuff.com/|Automate the Boring Stuff with Python]]: curso gratuito.
* [[http://pythontutor.com/|Python Tutor: Visualize code execution]]: visualiza la ejecución paso a paso de código Python.
* [[https://www.kaggle.com/datasets|Kaggle]]: conjunto de datos (datasets) abiertos.
* [[https://developers.google.com/edu/python|Google for Education: Python]]
* [[https://python101.pythonlibrary.org/|Python 101]]: curso gratuito de Python 3
* [[https://pythonprinciples.com/|Python Principles]]: curso online de programación en Python
* [[https://hackr.io/blog/python-projects|Cool, Fun & Easy Python Projects for Beginners (with Code)]]
* [[https://www.youtube.com/watch?v=OSGv2VnC0go|Transforming Code into Beautiful, Idiomatic Python]] (YouTube)
* [[https://www.youtube.com/watch?v=PtBHnMMRI0E|Python en 8 Minutos]] (YouTube)