Thema: python
-
Ein Python-Kommandozeilenwerkzeug entwerfen: argparse, main() und Exit-Codes
Die Schnittstelle in eine als Konsolenskript registrierte Funktion main(argv) -> int legen, mit den argparse-Parametern type und choices validieren, der Exit-Code-Konvention folgen (0 Erfolg, 2 Aufruffehler, 1 sonstiger Fehlschlag, sysexits-Codes nur wenn dokumentiert), Ergebnisse auf stdout und Diagnosemeldungen auf stderr ausgeben sowie SIGINT und abgebrochene Pipes behandeln.
-
Ein Konfidenzintervall für einen Median, ein Perzentil oder ein Verhältnis per Bootstrap ermitteln
Die Rohbeobachtungen viele Male mit Zurücklegen neu ziehen, die Statistik für jede Ziehung berechnen und das Intervall aus der entstehenden Verteilung ablesen; das liefert eine Unsicherheit für Mediane, Perzentile, Verhältnisse und Differenzen, für die keine Lehrbuchformel gilt. Methode, Anzahl der Ziehungen und Stichprobengrösse angeben und dem Verfahren bei extremen Perzentilen kleiner Stichproben nicht vertrauen.
-
Property-based Testing mit generierten Eingaben
Statt handverlesener Beispiele formuliert ein Property-based Test eine Invariante und lässt eine Bibliothek viele Eingaben generieren, wobei Fehlschläge auf minimale Gegenbeispiele verkleinert (shrinking) werden; Hypothesis ist die Referenzimplementierung für Python.
-
Kontextmanager in Python: Aufräumen garantieren
Die with-Anweisung führt __enter__ und __exit__ um einen Block herum aus, sodass Dateien, Sperren und Verbindungen auch bei einer Ausnahme freigegeben werden; contextlib.contextmanager macht aus einem Generator einen Kontextmanager.
-
Docstrings, die Werkzeuge und Leserinnen und Leser nutzen können
PEP 257 legt fest, wo Docstrings stehen und wie sie formatiert werden; ein einheitlicher Stil (Google oder NumPy) mit einzeiliger Zusammenfassung, Beschreibung von Argumenten und Rückgabewerten sowie ausgelösten Ausnahmen macht sie für Lesende, Editoren und Dokumentationsgeneratoren nutzbar.
-
Gleitkommazahlen: warum 0.1 + 0.2 nicht 0.3 ergibt
Binäre Gleitkommazahlen stellen die meisten Dezimalbrüche nur näherungsweise dar, sodass sich bei Rechnungen Rundungsfehler ansammeln; mit Toleranzen vergleichen, sorgfältig summieren, für Geldbeträge und Zählwerte Ganzzahlen oder Decimal-Typen verwenden und mit genügend Nachkommastellen ausgeben, damit ein Roundtrip gelingt.
-
YAML sicher laden
Volle YAML-Loader können aus getaggten Knoten beliebige Objekte instanziieren; stets einen sicheren Loader verwenden, die YAML-Versionssemantik festnageln und das Ergebnis vor der Verwendung gegen ein Schema validieren.
-
Wann asyncio hilft und wann nicht
asyncio führt viele E/A-lastige Aufgaben auf einem Thread aus, indem es an await-Punkten pausiert; es beschleunigt CPU-lastigen Code nicht, und blockierende Aufrufe innerhalb von Coroutinen legen die gesamte Event-Loop lahm.
-
Automatisierte Formatierung und Linting als Team-Vereinbarung
Layout an einen Formatter und mechanische Prüfungen an einen Linter zu delegieren, nimmt Stildiskussionen aus dem Review; EditorConfig, PEP 8 und Werkzeuge wie Ruff zeigen, wie sich die Vereinbarung im Repository festhalten lässt.
-
Protocol-Klassen: strukturelle Typisierung für duck-typed Python
Eine typing.Protocol deklariert die Methoden und Attribute, die eine konsumierende Stelle braucht; jedes Objekt, das sie besitzt, erfüllt den Typ, ohne davon zu erben. Protokolle neben dem Code definieren, der von ihnen abhängt, sie minimal halten und runtime_checkable nur dort einsetzen, wo isinstance wirklich gebraucht wird.
-
Einen Memory Leak mit tracemalloc-Snapshots finden
Das Tracing früh mit PYTHONTRACEMALLOC oder tracemalloc.start(nframe) starten, nach dem Aufwärmen einen Snapshot nehmen und einen weiteren nach N Iterationen, Import-Rauschen herausfiltern und compare_to(..., 'lineno') nach Zeilen absuchen, deren Grösse proportional zu N wächst; für die Aufrufer auf die Gruppierung 'traceback' wechseln.
-
Geld und andere exakte Grössen: Decimal statt float verwenden
Binäre Gleitkommazahlen können die meisten dezimalen Brüche nicht exakt darstellen, sodass Summen von Preisen driften; das Modul decimal bietet exakte Dezimalarithmetik mit expliziter Rundung, und Ganzzahlen in Kleinsteinheiten sind eine Alternative.
-
Zwischen Threads, Prozessen und asyncio für eine Python-Arbeitslast wählen
Zuerst den Hot Path klassifizieren: Warten auf I/O passt zu asyncio (viele Verbindungen, asynchrone Bibliotheken) oder zu einem Thread-Pool (wenige blockierende Aufrufe); reine Python-CPU-Arbeit braucht Prozesse oder einen Free-Threaded-Build; nativer Code, der das GIL freigibt, kann Threads nutzen. Jeden Pool begrenzen, die Prozess-Startmethode explizit wählen und den Abschaltpfad schreiben.
-
Dataclasses für einfache Records
dataclasses erzeugen __init__, __repr__ und Gleichheit aus annotierten Feldern; frozen dataclasses ergeben unveränderliche Werteobjekte, slots reduzieren den Speicherbedarf, und field(default_factory=...) vermeidet geteilte veränderliche Defaultwerte.
-
Bei welcher Arbeitslast übertrifft der Free-Threaded-CPython-Build einen Prozess-Pool für einen gemischten E/A- und CPU-Dienst?
Offene Frage: Der Free-Threaded-Build entfernt den GIL, fügt aber Overhead im Einzelthread-Betrieb hinzu und kann beim Import einer nicht vorbereiteten Extension auf den GIL zurückfallen, während Prozess-Pools für Pickling und Speicherverdopplung bezahlen; bei welchen Verhältnissen von CPU-Zeit zu Wartezeit, welchen Working Sets und welchen Kernzahlen liefert ein Thread-Pool auf dem Free-Threaded-Build mehr Durchsatz pro Kern?
-
Eine Aufgabe vor dem Lesen ihrer Musterlösung zu versuchen, ergibt eine bessere einmonatige Erinnerung an ein Sprachfeature als zuerst die Lösung zu lesen
Hypothese: Für eine Entwicklerin, die ein bestimmtes Sprachfeature lernt, etwa Pythons match-Anweisung, führt das Bearbeiten einer Aufgabe vor dem Betrachten der Musterlösung zu besserer verzögerter Erinnerung und besserem Transfer als zuerst die Lösung zu studieren und danach eine ähnliche Aufgabe zu bearbeiten; ein vorgeschlagener Within-Person-Test mit zwei Features, zwei Reihenfolgen und einem einmonatig verzögerten Test, ohne behauptetes Ergebnis.
-
Iterables versus Iteratoren: das Protokoll hinter for-Schleifen
Ein Iterable liefert über __iter__ einen frischen Iterator zurück; ein Iterator liefert Elemente über __next__, wirft StopIteration, wenn er fertig ist, und muss dabei bleiben. Eine for-Schleife ruft iter einmal und next wiederholt auf, weshalb ein erschöpfter, an eine zweite Schleife übergebener Iterator leer erscheint. Iterable für einen einzelnen Durchlauf annotieren, Sequence oder Collection, wenn mehrere gebraucht werden.
-
Code testen, der von Zeit und Zufall abhängt
Statt time.time() oder random direkt aufzurufen, eine Uhr und eine Zufallsquelle injizieren; Tests übergeben dann feste Werte, und der Code bleibt deterministisch und reproduzierbar.
-
Deserialisierung nicht vertrauenswürdiger Daten: pickle und Java-Serialisierung
Native Objektserialisierungsformate weisen den Empfänger an, beliebige Objekte zu konstruieren, und das Konstruieren von Objekten führt Code aus; die Python-Dokumentation zu pickle sagt unumwunden, dass das Modul nicht sicher ist. Diese Formate niemals aus nicht vertrauenswürdiger Eingabe deserialisieren; wo eine Altschnittstelle es erzwingt, die Klassen einschränken, die der Datenstrom benennen darf, und die Nutzlast signieren.
-
Externe Befehle sicher aus Python heraus ausführen
subprocess.run mit einer Argumentliste und shell=False verwenden, Timeouts setzen, die Ausgabe explizit erfassen, Rückgabecodes prüfen und niemals eine Befehlszeile aus nicht vertrauenswürdigen Zeichenketten zusammenbauen.
Maschinenlesbar: JSON