
C'est une nouvelle sélection de trucs et astuces sur Python et la programmation de mon canal Telegram @pythonetc.
Plusieurs gestionnaires de contexte
Parfois, vous souhaitez exécuter un bloc de code avec 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, vous pouvez le faire avec un seul
with
expression:
o = open with o('f') as f, o('g') as g, o('h') as h: pass
Avant cela, vous pouviez utiliser la fonction contextlib.nested:
with nested(o('f'), o('g'), o('h')) as (f, g, h): pass
Si vous travaillez avec le nombre inconnu de gestionnaire de contexte, l'outil plus avancé vous convient bien.
contextlib.ExitStack
vous permet d'entrer n'importe quel nombre de contextes à un moment arbitraire mais garantit de les quitter à la fin:
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 existent actuellement dans la mémoire de l'interpréteur sont accessibles via
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)]
Symboles numériques
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 traite plusieurs centaines de symboles comme des chiffres, voici la liste complète (http://www.fileformat.info/info/unicode/category/Nd/list.htm).
Cela affecte 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 minuit
>>> bool(datetime(2018, 1, 1).time()) False >>> bool(datetime(2018, 1, 1, 13, 12, 11).time()) True
Avant Python 3.5, les objets
datetime.time()
étaient considérés comme faux s'ils représentaient UTC à minuit. Cela peut conduire à des bugs obscurs. Dans les exemples suivants,
if not
peut
if not
s'exécuter parce que
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 résoudre ce problème en testant explicitement
None
:
if created_time is None
.
Opérations sur les fichiers asynchrones
Il n'y a pas de prise en charge en Python pour les opérations de fichiers asynchrones. Pour les rendre non bloquants, vous devez utiliser des threads séparés.
Pour exécuter du code de manière asynchrone dans le thread, vous devez utiliser la méthode
loop.run_in_executor
.
Le module
aiofiles
tiers fait tout cela pour vous en fournissant une interface agréable et simple:
async with aiofiles.open('filename', mode='r') as f: contents = await f.read()
Source:
habr.com/ru/company/mailru/blog/436322