Está en la página 1de 20

Trucos útiles De Python

Eduardo Zepeda

2022-07-19

Contents

Las dos funciones más infravaloradas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

dir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

El ternario de Python desconocido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Trabajando con secuencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Invierte un array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Creando copias superficiales de una secuencia . . . . . . . . . . . . . . . . . . . . . . . . 4

Zip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Enumerate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

Counter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Dequeue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

NamedTuple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

Mide el rendimiento de tu código con timeit, Cprofile . . . . . . . . . . . . . . . . . . . . . . . . 7

timeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

Cprofile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Atributos protegidos y privados en Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Guión sencillo: _attr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Doble guión: __attr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

Usa el tiempo monotónico para medir . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Dataclasses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

Desestructuración de iterables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Listas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

1
Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

Diccionarios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Aprovecha los métodos mágicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Personalizar lo que muestra print: __str__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

Inicializar una instancia: __init__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Establecer atributos: __setattr__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

Acceder a atributos: __getattr__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Borrar atributos: __delattr__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

Iteradores con: __iter__ y __next__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

Limita la ejecución del código con __name__ == ’__main__’ . . . . . . . . . . . . . . . . . . . . . 16

__name__ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

’__main__’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

Crea tu propio context manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

Bonus: Otros intérpretes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Bonus: Un poco sobre swig . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

Como ya sabes, Python es un lenguaje bastante simple de aprender, esta simplicidad abstrae muchísi-

mas funcionalidades y nos permite realizar casi todo de una manera directa. Sin embargo hay una serie

de funciones o características que, por la simplicidad del lenguaje, pasan inadvertidas para numerosos

desarrolladores. Estos trucos son características del lenguaje o librerías menos populares, pero no por

eso menos útiles.

Las dos funciones más infravaloradas

A veces cuando tenemos duda de como funciona algun objeto o función interna de Python vamos di-

recto a google y buscamos el problema, casi siempre esto nos dirige a la documentación oficial o algún

blog bien optimizado. ¿Y si te digo que podrías haber obtenido la misma información sin abandonar la

terminal, desde el intérprete de Python?

help

La función help tomará un objeto como argumento y te imprimirá en pantalla el texto de ayuda, toda

la información que necesitas saber sobre un objeto con su descripción, funciones y la ubicación en el

sistema de archivos del módulo.

2
help(<objeto>)

Ejemplo:

import math

help(math)

# Help on module math:

# NAME

# math

# MODULE REFERENCE

# https://docs.python.org/3.9/library/math

dir

La función dir tomará un objeto como argumento y te imprimirá en pantalla los métodos del objeto y

sus atributos. Es bastante útil para saber con que métodos y atributos contamos en un objeto.

dir(<objeto>)

Ejemplo:

import math

dir(math)

# ['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin',

El ternario de Python desconocido

¿Sabías que Python tiene algo parecido a un operador ternario? Sí, como el de javascript y otros lengua-

jes, para llevar a cabo flujos de tipo if…else en una sola linea.

El ternario de Python guarda la siguiente sintaxis:

<retorna esto> if <condicion> else <retorna esto otro>

Por ejemplo:

numero = 2

"Es un dos" if numero == 2 else "No es un dos"

3
Trabajando con secuencias

Invierte un array

Para invertir un array podemos usar este simple truco.

<arr>[::-1]

Ejemplo:

arr = [1,2,3]

print(arr[::-1])

# [3,2,1]

Creando copias superficiales de una secuencia

Podemos realizar una copia superficial de un array usando [:]

¿Por qué superficial? Porque no crea dos objetos distintos, sino que guarda una referencia al mismo

objeto.

<secuencia>[:]

Ejemplo:

arr = [[1,2,3], [4,5,6]]

copyArr = arr[:]

Ahora los índices de ambos arrays apuntan hacia el mismo objeto.

arr[0] is copyArr[0]

True

Debido a lo anterior, si realizamos un cambio a la referencia, ambos arrays se verán modificados.

arr[0][0] = "Esto también será diferente en copyArr"

print(copyArr)

# [['Esto también será diferente en copyArr', 2, 3], [4, 5, 6]]

Para crear una copia profunda, en la que se cree otro objeto se usa la función deepcopy.

import copy

arrCopy = copy.deepcopy(arr)

4
Otra manera de hacerlo es desestructurando un array, te explico como más adelante.

Zip

Zip permite unir cualquier número iterables en una lista de tuplas. Zip (cierre en inglés) funciona exac-

tamente igual que un cierre de ropa, en el que un diente de un lado se une a un diente del otro.

zip(*iterables)

Dado que devuelve un objeto zip, es necesario combinarlo con list para obtener una representación

más amigable.

Ejemplo:

zip([1,2,3], ["Uno","Dos","Tres"])

# <zip object at 0x7fe24255ffc0>

list(zip([1,2,3], ["Uno","Dos","Tres"]))

# [(1, 'Uno'), (2, 'Dos'), (3, 'Tres')]

Enumerate

Enumerate toma un iterable y le asigna un índice, combina muy bien cuando lo combina usando ciclos

for.

enumerate(<iterable>, start=0)

Ejemplo:

list(enumerate(["sol", "nube", "estrella"]))

for index, emoji in enumerate(["sol", "nube", "estrella"]):

print(index, emoji)

# 0 sol

# 1 nube

# 2 estrella

5
Counter

La librería collections cuenta con múltiples funciones útiles, entre ellas Counter, que se encarga de

contar un iterable o mapping

Counter(<iterable>=None, /, **kwds)

Ejemplo:

from collections import Counter

array = ["sol", "nube", "nube", "estrella", "estrella", "estrella"]

Counter(array)

# Counter({'estrella': 3, 'nube': 2, 'sol': 1})

Dequeue

Dequeu es una cola doble que soporta la adición o eliminación de ambos extremos en un tiempo de

O(1).

En contraste, las listas normales incurren en O(n) cuando se inserta un elemento del lado izquierdo;

cuando usamos pop(0) e insert(0, v).

deque([<iterable>[, maxlen]])

Ejemplo:

from collections import deque

cola = deque("1")

cola.appendleft("0")

cola.pop()

# "2"

cola.popleft()

# "0"

NamedTuple

Las namedtuple nos permiten crear tuplas con nombres, facilitan el acceso a los elementos de una

tupla y el manejo de estos objetos usando propiedades, en lugar de índices. Mejorarán enormemente

6
la legibilidad de tu código, tanto para ti como para tu equipo.

namedtuple(typename, field_names, *, rename=False, defaults=None, module=None)

En una tupla normal tendríamos que usar índices para acceder a los valores. El problema con esta

aproximación es que necesitas conocer el índice correcto de antemano para acceder a las propiedades

de las tuplas, lo cual coloca la responsabilidad de saber que atributo representa cada número en el

desarrollador.

producto = ('La Biblioteca de la Medianoche', 200)

producto[0]

# 'La Biblioteca de la Medianoche'

producto[1]

# 200

Pero si, en lugar de una tupla normal, usamos una tupla con nombre, podemos tratarla como si se

tratara de un objeto, accediendo a los nombres de las propiedades, en lugar de a sus índices.

from collections import namedtuple

producto = namedtuple('Producto', ['nombre', 'precio'])

libro = producto('La Biblioteca de la Medianoche', 200)

libro

# Producto(nombre='La Biblioteca de la Medianoche', precio=200)

libro.precio

# 200

Mide el rendimiento de tu código con timeit, Cprofile

Python se caracteriza por ser un lenguaje lento, en lugar de reescribir los cuellos de botella en un

lenguaje de bajo nivel o cambiar por completo el código, quizás prefieras refactorizar cualquier código

que no sea tan eficiente, pero para eso necesitas medirlo primero. Son pocos los desarrolladores que

saben sobre las herramientas de perfilado que existen en Python y lo sencillas de usar que son.

timeit

Timeit se encarga de repetir múltiples veces una función para calcular el tiempo que consume.

7
Podemos perfirlar el código Python desde la terminal.

python3 -m timeit '"-".join(str(n) for n in range(100))'

# 20000 loops, best of 5: 18.6 usec per loop

O directamente desde el intérprete de Python.

import timeit

timeit.timeit('"-".join(str(n) for n in range(100))', number=10000)

# 0.20822427999974025

Con el parámetro number podemos aumentar o disminuir el número de repeticiones a nuestro gusto.

Cprofile

Cprofile va a recibir una función a ejecutar y nos imprimirá una tabla donde se muestran la trazabili-

dad de las funciones que se ejecutaron, el número de veces, la duración de la ejecución y el tiempo

acumulado entre ellas.

import cProfile

import re

cProfile.run('re.compile("foo|bar")')

Atributos protegidos y privados en Python

Como ya sabes, Python no cuenta con las palabras reservadas private y protected para limitar el acceso

a los atributos de un miembro de una clase de manera “real”. Sin embargo existe una convención muy

fuerte que deberías seguir respecto a esto.

Guión sencillo: _attr

Colocar un guión bajo antes de un atributo indica que su uso debe ser interno, sin embargo el intér-

prete de Python forzará que se respete esto. Es más una especie de nota para los desarrolladores que

trabajen en tu código que les dice que no deben acceder a la variable desde fuera.

class Persona:

def __init__(self):

self._name = "Nombre"

8
Si intentamos acceder a esta propiedad no pasará nada.

persona = Persona()

persona._name

# Nombre

Doble guión: __attr

Un doble guión bajo antes de una propiedad indica que una prohibición al acceso de un atributo fuera

de este, el intérprete de Python si fuerza que se respeta. ¿Cómo lo consigue? Python cambian el

nombre de cualquier atributo que empiece por dos guoines bajos para que no pueda accederse de

manera directa.

Ejemplo:

class Persona:

def __init__(self):

self._name = "Nombre"

self.__secret_name = "Nombre secreto"

Si intentamos acceder directamente al atributo con el nombre de atributo que usamos obtendremos

un error por parte del intérprete.

persona = Persona()

persona.__secret_name

Traceback (most recent call last):

File "/home/usuario/script.py", line 12, in <module>

print(persona.__secret_name)

AttributeError: 'Persona' object has no attribute '__secret_name'

Pero si revisamos todos los atributos de nuestro objeto, con la función dir, veremos que realmente la

variable ha sido renombrada usando la siguiente sintaxis ___, en este caso *_Persona__secret_name*.

Si intentas acceder al atributo usando ese nombre podrás acceder al contenido, pero no deberías, de-

spués de todo alguien uso el doble guión bajo para que no lo hicieras.

9
dir(persona)

['_Persona__secret_name', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__for

Usa el tiempo monotónico para medir

Cuando usamos el módulo time para medir el tiempo en Python, Python toma la referencia al tiempo del

sistema. Esto está bien para la mayoría de los casos, pero imagínate que tienes un proceso muy largo y

hay alguien jugando con el tiempo del sistema, lo anterior echaría a perder tu medición por completo.

Para usar un tiempo “real”, que no dependa del tiempo del sistema, usamos el tiempo monotónico.

import time

inicio = time.monotonic()

# Aquí va lo que quieres medir

final = time.monotonic()

print(final - inicio)

Dataclasses

Es bastante común la inicialización de objetos con atributos personalizables, que pasa un usuario. El

patrón común al hacer esto es requerir los atributos como argumentos.

class Cuenta:

"""Modelo de cuenta básica con username, nombre y edad"""

def __init__(self, username, nombre, edad):

self.username = username

self.nombre = nombre

self.edad = edad

Esto está bastante bien, pero podemos tener una sintaxis más limpia usando el decorador dataclass. El

ejemplo anterior es equivalente a este.

from dataclasses import dataclass

10
class Cuenta:

"""Modelo de cuenta básica con username, nombre y edad"""

username: str

nombre: str

edad: int

Desestructuración de iterables

Igual que en Javascript podemos desestructurar un iterable, para crear una copia o extender otro iter-

able.

Listas

Para desestructurar una lista, usamos el operador de desestructurización, el asterisco, antes de la ref-

erencia a la lista.

arr = [1, 2, 3]

otro_arr = [*arr]

Podemos crear nuevos arrays a partir de cualquier número de desestructuraciones.

arr = [1, 2, 3]

arr2 = [4, 5, 6]

mezcla_de_arr = [*arr, *arr2]

La sintaxis anterior no es aplicable a las tuplas, pues estos no pueden desestructurarse.

Sets

De la misma manera que los arrays, los sets pueden desestructurarse siguiendo la misma sintaxis.

sett1 = {1, 2, 3, 4}

sett2 = {4, 5, 6, 7}

otro_set = {*sett1, *sett2}

11
Diccionarios

Para desestructurar un diccionario lo haremos igual que una lista, pero usando dos asteriscos, en lugar

de uno.

primer_dict = {"uno": 1, "dos": 2}

nuevo_dict = { **primer_dict }

De la misma manera, podemos desestructurar tantos diccionarios como querramos para crear otro

primer_dict = {"uno": 1, "dos": 2}

segundo_dict = {"tres": 3, "cuatro": 4}

nuevo_dict = { **primer_dict, **segundo_dict }

Aprovecha los métodos mágicos

Los métodos mágicos no tienen nada de mágicos, pero te ayudan a personalizar el comportamiento

de un objeto. También se les llama métodos dunder (de double underscore).

Puedes entenderlos como métodos especiales de un objeto que se ejecutan solo bajo ciertas condi-

ciones. Por ejemplo: cuando se crea una instancia de un objeto, o cuando se establece un atributo, o

cuando se lee un atributo, etc.

Su sintaxis es la siguiente:

def __<nombre_del_metodo>__(self):

pass

Puedes pensar en el doble guión al principio como una señal de que no debes llamarlos de manera

directa, sino que se llamarán “solos” cuando tu realices acciones sobre el objeto que las implementa.

Personalizar lo que muestra print: __str__

Uno de los más conocidos, se llama cuando se ejecuta el método print sobre un objeto. En Django se

usa para devolver la representación de un modelo.

class MagicMethods(object):

def __str__(self):

return "Cuando se imprima una instancia se mostrará este texto"

12
magic = MagicMethods()

print(magic)

# Cuando se imprima una instancia se mostrará este texto

Como ejecutamos la función print sobre el objeto, se llamó al método automáticamente.

Inicializar una instancia: __init__

Init se llama cuando se inicializa una instancia de un objeto, es el método ideal para asignar atributos

que provengan de los argumentos

class MagicMethods(object):

def __init__(self, *args, **kwargs):

self.primer_argumento = args[0]

print("Inicializando el objeto")

print("Con argumentos:", *args)

magic = MagicMethods(1, "dos", {"3": 3})

# Inicializando el objeto

# con argumentos: 1 dos {'3': 3}

Establecer atributos: __setattr__

Se llama cuando se establece un atributo. Tiene dos compañeros: ### __getattr__ y ### __delattr__,

que se llaman cuando se intenta acceder a un atributo que no existe y cuando se intenta borrar un

atributo, respectivamente.

class Persona(object):

def __init__(self, name):

self.name = name

def __setattr__(self, name, value):

print("Asignamos %s a %s" % (name, value))

13
self.__dict__[name] = value

def __delattr__(self, name):

print("Intentando borrar: ", name)

Cuando creamos el objeto, se establecerá el atributo y se llamará __setattr__. Mira como accedemos

al método mágico *__dict__*, puesto que si hicieramos la asignación de manera normal entrariamos en

un bucle infinito.

Acceder a atributos: __getattr__

__getattr__ se llama si intentamos acceder an atributo que no existe, dentro de este método seremos

capaces de retornar un valor, o cualquier otro comportamiento que querramos.

class Persona(object):

# ...

def __getattr__(self, name):

print("Intentando acceder a: ", name)

return "no existe"

a.atributo_inexistente

# Intentando acceder a: atributo_inexistente

# no existe

Borrar atributos: __delattr__

__delattr__ se llama cuando intentamos eliminar un atributo de un objeto, dentro del método podemos

personalizar el comportamiento, desde notificar sobre esto o bloquear por completo el bloqueo.

En este ejemplo borramos el atributo y lo informamos en la terminal.

class Persona(object):

# ...

14
def __delattr__(self, name):

print("Intentando borrar: ", name)

del self.__dict__[name]

print("Se borró exitosamente")

Iteradores con: __iter__ y __next__

Los siguientes métodos generalmente se utilizan juntos y son muy útiles al momento de crear iter-

adores personalizados. Imagínate un iterador que genere potencias de dos, o números primos, o

cualquier otra cosa que quieras.

__iter__ Este método se llama cuando se crea un iterador, normalmente retornamos el mismo objeto,

a través de self, para que en cada una de las siguientes interacciones podamos llamar a su método

__next__

class StringIncremental():

def __iter__(self):

self.cadena = ""

return self

__next__ __next__ se llama en cada una de las iteraciones de un objeto. Hay que recordar que este

método tiene que levantar una excepción para avisarle a nuestro ciclo que debe terminar y evitar bucles

infinitos.

class StringIncremental():

def __iter__(self):

self.cadena = ""

return self

def __next__(self):

15
self.cadena += "a"

if len(self.cadena) > 4:

print("Se termina la iteración")

raise StopIteration

return self.cadena

Mira como funciona el iterador.

iterador = StringIncremental()

for letra in iterador:

print(letra)

# a

# aa

# aaa

# aaaa

# Se termina la iteración

Limita la ejecución del código con __name__ == ’__main__’

Si has visto esta comprobación en algunos scripts de Python y no entiendes como funciona.

if __name__=='__main__':

Este pequeño trozo de código se usa para que solo se ejecute el código si lo pasamos directamente al

intérprete de Python, y que no se ejecute cuando lo importamos desde otro archivo.

¿Cómo funciona? Te lo explica ahora mismo.

__name__

El intérprete de Python asigna automáticamente un nombre a cada archivo que ejecuta y lo guarda en

una variable de nombre __name__. ¿Te fijas que en ningún momento declaramos __name__?

Imagina un archivo que solo tiene una función sencilla.

# libreria.py

def suma(a, b):

return a + b

16
print(__name__)

Ahora imagina que tienes un archivo que importa el archivo anterior.

# main.py

import libreria

Si usamos el intérprete de Python para ejecutar el archivo, observaremos que la función print se ejecu-

tará y se imprimirá en pantalla el nombre de la librería.

python main.py

# libreria

’__main__’

Cuando ejecutamos un archivo de Python usando el intérprete, este le asigna el string ’__main__’ a la

variable __name__ al archivo en ejecución.

Vamos a modificar el archivo main.py para que imprima su nombre.

# main.py

print(__name__)

Si ahora ejecutamos bash.

python main.py

# __main__

¿Y esto en que nos sirve? Es bastante útil para saber si el archivo en el que estamos está siendo ejecu-

tado por Python o siendo importado por otro archivo.

Si el archivo está siendo importado, __name__ no será igual a ’__main__’.

Por otro lado, si el archivo no está siendo importado, es decir, está siendo ejecutado directamente por

el intérprete de Python, __name__ será igual a ’__main__’ y se ejecutará la condición.

if __name__== '__main__':

main()

17
Crea tu propio context manager

¿Recuerdas esa sintaxis de Python que te permite cerrar automáticamente el stream de archivos?

with open("archivo.txt", "r") as f:

contenido = f.readlines()

Con esta sintaxis ya no tienes que llamar al método f.close() para cerrar el archivo, Python lo hace

automáticamente. Gracias al context manager se automatizó esta tarea.

Con Python tú también puedes crear tus propias clases que sirvan como context manager. Estas

pueden servirte para cerrar conexiones a base de datos, conexiones HTTP pendientes, o cualquier

otra acción que requiera tu código.

Ok, ok, pero ¿cómo se crea el context manager?

Simplemente declarando dos métodos especiales en tu clase:

• enter() Se llama con la palabra with, al iniciar el contexto de ejecución.

• exit() Se ejecuta cuando se abandona el contexto de ejecución, es decir, al salir del bloque with.

class context_manager():

def __enter__(self):

print("Bienvenido al contexto")

return "Valor de retorno del contexto"

def __exit__(self, exc_type, exc_value, exc_tb):

print("Abandonando el contexto")

Al ejecutar nuestra nueva clase en un contexto usando with verás lo que sucede

with context_manager() as ctx:

print(ctx)

# Bienvenido al contexto

# Valor de retorno del contexto

# Abandonando el contexto

18
¿Qué acaba de pasar? Te explico lo que sucede al ejecutar nuestro bloque with en orden:

1. Se ejecuta la función enter y se imprime el mensaje de bienvenida

2. La función enter termina de ejecutarse y devuelve un valor que se imprime con la función print

que está en el interior del bloque with

3. El bloque with termina su ejecución y se llama al método exit

Habrás notado que la función exit tiene una serie de argumentos especiales. Los parámetros que recibe

la función se usan para manejar excepciones. Cuando una excepción ocurre, exc_type, exc_value, and

exc_tb, contendrán el tipo de excepción, el valor y la información de seguimiento, respectivamente.

Bonus: Otros intérpretes

Python es un lenguaje interpretado y que no destaca precisamente por su velocidad. Debido a lo ante-

rior, otros desarrolladores se han dado la tarea de crear alternativas mejoradas al intérprete predeter-

minado de Python que pueden significar mejoras gigantescas en el desempeño de Python.

Se usan exactamente igual que usarías el intérprete normal, pero algunos no son totalmente compati-

bles con todo el código Python, por lo que asegúrate de revisar sus limitaciones y casos de uso en sus

sitios web oficiales.

• PyPy

• Stackless Python

• Jython

• IronPython

• GraalPython

Bonus: Un poco sobre swig

¿Preocupado por el rendimiento de Python? Swig es una herramienta que te permite escribir código

en C o C++ y, posteriormente, llamarlo desde Python. El proceso es algo tedioso, pero muy mecánico,

no hay que pensar demasiado, solo hay que ejecutar una serie de comandos (que no cubriré aquí) tras

lo cual tendrás una librería importable que funciona usando código compilado que te ofrecerá lo mejor

de los dos mundos: la legibilidad de un lenguaje de alto nivel, con la velocidad de un lenguaje de bajo

nivel.

Con lo anterior doy por terminado esta pequeña guía de trucos de Python.

19
Nos vemos la siguiente semana en tu bandeja de entrada.

20

También podría gustarte