
Esta es la séptima selección de consejos y programación de Python de mi feed @pythonetc.
Selecciones anteriores:
Múltiples contextos
A veces puede ser necesario ejecutar un bloque de código en varios administradores de contexto:
with open('f') as f: with open('g') as g: with open('h') as h: pass
Desde Python 2.7 y 3.1, esto se puede hacer con una sola expresión:
o = open with o('f') as f, o('g') as g, o('h') as h: pass
Antes, podría usar la función
contextlib.nested
:
with nested(o('f'), o('g'), o('h')) as (f, g, h): pass
Si trabaja con un número indefinido de administradores de contexto, es mejor elegir herramientas más avanzadas.
contextlib.ExitStack
permite ingresar cualquier número de contextos en cualquier momento y garantiza la salida de ellos al final de la ejecución:
with ExitStack() as stack: f = stack.enter_context(o('f')) g = stack.enter_context(o('g')) other = [ stack.enter_context(o(filename)) for filename in filenames ]
Objetos en la memoria del intérprete
Se puede acceder a todos los objetos que están actualmente en la memoria del intérprete usando
gc.get_objects()
:
In : class A: ...: def __init__(self, x): ...: self._x = x ...: ...: def __repr__(self): ...: class_name = type(self).__name__ ...: x = self._x ...: return f'{class_name}({x!r})' ...: In : A(1) Out: A(1) In : A(2) Out: A(2) In : A(3) Out: A(3) In : [x for x in gc.get_objects() if isinstance(x, A)] Out: [A(1), A(2), A(3)]
Dígitos
In : int('୧৬༣') Out: 163
0 1 2 3 4 5 6 7 8 9
no son los únicos caracteres considerados dígitos. Python sigue las reglas de Unicode y cuenta varios cientos de caracteres como números. Lista completa
aquí .
Esto es importante para funciones como
int
,
unicode.isdecimal
e incluso
re.match
:
In : int('௯') Out: 9 In : '٢'.isdecimal() Out: True In : bool(re.match('\d', '౫')) Out: True
UTC Midnight
>>> bool(datetime(2018, 1, 1).time()) False >>> bool(datetime(2018, 1, 1, 13, 12, 11).time()) True
Antes de Pyhon 3.5, los objetos
datetime.time()
se consideraban falsos si representaban la medianoche UTC. Esto puede conducir a errores no evidentes. En el siguiente ejemplo,
if not
puede fallar porque no
create_time
es
None
, pero porque es medianoche.
def create(created_time=None) -> None: if not created_time: created_time = datetime.now().time()
Puede evitar este error marcando explícitamente
None
:
if created_time is None
.
Trabajo asincrónico en FS
Python no admite operaciones de archivo asincrónicas. Para que no se bloqueen, debes usar hilos.
Para la ejecución de código asíncrono en una secuencia, debe usar el método
loop.run_in_executor
.
Un módulo de
aiofiles
terceros puede hacer esto por usted, proporcionando una interfaz conveniente y simple:
async with aiofiles.open('filename', mode='r') as f: contents = await f.read()