Tipps und Tricks aus meinem Telegrammkanal @pythonetc, Dezember 2019



Es ist eine neue Auswahl von Tipps und Tricks zu Python und Programmierung aus meinem Telegramm-Kanal @pythonetc.

Frühere Publikationen .


Unterschiedliche asyncio Aufgaben haben offensichtlich unterschiedliche Stapel. Sie können sie jederzeit mit asyncio.all_tasks() , um alle aktuell ausgeführten Tasks task.get_stack() und task.get_stack() , um einen Stapel für jede Task task.get_stack() .

 import linecache import asyncio import random async def producer(queue): while True: await queue.put(random.random()) await asyncio.sleep(0.01) async def avg_printer(queue): total = 0 cnt = 0 while True: while queue.qsize(): x = await queue.get() total += x cnt += 1 queue.task_done() print(total / cnt) await asyncio.sleep(1) async def monitor(): while True: await asyncio.sleep(1.9) for task in asyncio.all_tasks(): if task is not asyncio.current_task(): f = task.get_stack()[-1] last_line = linecache.getline( f.f_code.co_filename, f.f_lineno, f.f_globals, ) print(task) print('\t', last_line.strip()) print() async def main(): loop = asyncio.get_event_loop() queue = asyncio.Queue() loop.create_task(producer(queue)) loop.create_task(producer(queue)) loop.create_task(producer(queue)) loop.create_task(avg_printer(queue)) loop.create_task(monitor()) loop = asyncio.get_event_loop() loop.create_task(main()) loop.run_forever() 

Sie können stattdessen task.print_stack() aufrufen, um ein task.print_stack() Durcheinander mit dem linecache und die Verwendung des linecache Moduls zu vermeiden.


Sie können Zeichen eines Strings mit der translate Methode von str übersetzen oder löschen (wie es das tr Dienstprogramm tut):

 >>> 'Hello, world!'.translate({ ... ord(','): ';', ... ord('o'): '0', ... }) 'Hell0; w0rld!' 

Das einzige Argument für die translate ist ein Wörterbuch, das Zeichencodes Zeichen (oder Codes) zuordnet. Es ist normalerweise praktischer, ein solches Wörterbuch mit der statischen Methode str.maketrans zu erstellen:

 >>> 'Hello, world!'.translate(str.maketrans({ ... ',': ';', ... 'o': '0', ... })) 'Hell0; w0rld!' 

Oder sogar:

 >>> 'Hello, world!'.translate(str.maketrans( ... ',o', ';0' ... )) 'Hell0; w0rld!' 

Das dritte Argument dient zum Löschen von Zeichen:

 >>> tr = str.maketrans(',o', ';0', '!') >>> tr {44: 59, 111: 48, 33: None} >>> 'Hello, world!'.translate(tr) 'Hell0; w0rld' 


mypy unterstützt noch keine rekursiven Typdefinitionen:

 from typing import Optional, Dict from pathlib import Path TreeDict = Dict[str, 'TreeDict'] def tree(path: Path) -> TreeDict: return { f.name: tree(f) if f.is_dir() else None for f in path.iterdir() } 

Der Fehler lautet Cannot resolve name "TreeDict" (possible cyclic definition) .

Bleiben Sie hier auf dem Laufenden: https://github.com/python/mypy/issues/731


Gewöhnliche Funktionen müssen sich nur selbst aufrufen, um rekursiv zu werden. Für Generatoren ist das nicht so einfach: Für rekursive Generatoren muss in der Regel die yield from werden:

 from operator import itemgetter tree = { 'imgs': { '1.png': None, '2.png': None, 'photos': { 'me.jpg': None }, }, 'MANIFEST': None, } def flatten_tree(tree): for name, children in sorted( tree.items(), key=itemgetter(0) ): yield name if children: yield from flatten_tree(children) print(list(flatten_tree(tree))) 


Sie können for nicht nur mit Variablen, sondern mit jedem Ausdruck verwenden. Es wird bei jeder Iteration ausgewertet:

 >>> log2 = {} >>> key = 1 >>> for log2[key] in range(100): ... key *= 2 ... >>> log2[16] 4 >>> log2[1024] 10 

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


All Articles