
Ceci est la septième sélection de conseils et de programmation Python de mon flux @pythonetc.
Sélections précédentes:
Contextes multiples
Parfois, il peut être nécessaire d'exécuter un bloc de code dans plusieurs gestionnaires de contexte:
with open('f') as f: with open('g') as g: with open('h') as h: pass
Depuis Python 2.7 et 3.1, cela peut être fait avec une seule expression:
o = open with o('f') as f, o('g') as g, o('h') as h: pass
Avant, vous pouviez utiliser la fonction
contextlib.nested
:
with nested(o('f'), o('g'), o('h')) as (f, g, h): pass
Si vous travaillez avec un nombre indéfini de gestionnaires de contexte, il est préférable de choisir des outils plus avancés.
contextlib.ExitStack
vous permet d'entrer n'importe quel nombre de contextes à tout moment et garantit leur sortie à la fin de l'exécution:
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 ]
Objets dans la mémoire de l'interpréteur
Tous les objets qui sont actuellement dans la mémoire de l'interpréteur sont accessibles en utilisant
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)]
Chiffres
In : int('୧৬༣') Out: 163
0 1 2 3 4 5 6 7 8 9
ne sont pas les seuls caractères considérés comme des chiffres. Python suit les règles Unicode et compte plusieurs centaines de caractères sous forme de nombres. Liste complète
ici .
Cela compte pour des fonctions comme
int
,
unicode.isdecimal
et même
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
Avant Pyhon 3.5, les objets
datetime.time()
étaient considérés comme faux s'ils représentaient minuit UTC. Cela peut conduire à des bogues non évidents. Dans l'exemple suivant,
if not
peut échouer car pas
create_time
est
None
, mais parce qu'il est minuit.
def create(created_time=None) -> None: if not created_time: created_time = datetime.now().time()
Vous pouvez contourner ce bogue en vérifiant explicitement
None
:
if created_time is None
.
Travail asynchrone dans FS
Python ne prend pas en charge les opérations de fichiers asynchrones. Pour les rendre non bloquants, vous devez utiliser des threads.
Pour l'exécution de code asynchrone dans un flux, vous devez utiliser la méthode
loop.run_in_executor
.
Un module
aiofiles
tiers peut le faire pour vous, fournissant une interface simple et pratique:
async with aiofiles.open('filename', mode='r') as f: contents = await f.read()