
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/731Gewö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