@Pythonetc décembre 2018



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() 

Source: https://habr.com/ru/post/fr436322/


All Articles