4 leistungsstarke Funktionen Python fehlt noch

Python ist eine lebendige Sprache - ständig weiterentwickelt, um mit der Zeit Schritt zu halten. Die Python Software Foundation erweitert nicht nur die Standardbibliothek und die Referenzimplementierung CPython, sondern führt auch neue Funktionen und Verbesserungen in der Sprache selbst ein.

In Python 3.8 wurde beispielsweise eine neue Syntax für Inline-Zuweisungen eingeführt (der „Walross-Operator“), mit der bestimmte Vorgänge präziser gestaltet werden. Eine weitere neu genehmigte Syntaxverbesserung, der Mustervergleich, erleichtert das Schreiben von Code, der für einen von vielen möglichen Fällen ausgewertet wird. Beide Funktionen wurden durch ihre Präsenz und Nützlichkeit in anderen Sprachen inspiriert.

Und sie sind nur zwei von vielen nützlichen Funktionen, die Python hinzugefügt werden könnten, um die Sprache ausdrucksvoller, leistungsfähiger und für die moderne Programmierwelt besser geeignet zu machen. Was könnten wir uns sonst noch wünschen? Hier sind vier weitere Sprachfunktionen, die Python einen echten Mehrwert verleihen könnten - zwei, die wir möglicherweise tatsächlich erhalten, und zwei, die wir wahrscheinlich nicht erhalten werden. 

Wahre Konstanten

Python hat nicht wirklich das Konzept eines konstanten Wertes. Konstanten in Python sind heute meist eine Frage der Konvention. Die Verwendung eines Namens in Großbuchstaben und im Fall einer Schlange - z. B. DO_NOT_RESTART - ist ein Hinweis darauf, dass die Variable eine Konstante sein soll. In ähnlicher Weise gibt die  typing.Final Typanmerkung Lintern einen Hinweis darauf, dass ein Objekt nicht geändert werden sollte, erzwingt dies jedoch nicht zur Laufzeit.

Warum? Weil die Veränderlichkeit tief in Pythons Verhalten verwurzelt ist. Wenn Sie einer Variablen einen Wert zuweisen, z. B.,  x=3 erstellen Sie einen Namen im lokalen Namespace  xund zeigen ihn auf ein Objekt im System mit dem ganzzahligen Wert  3. Python geht jederzeit davon aus, dass Namen veränderbar sind - dass jeder Name auf ein beliebiges Objekt verweisen kann . Das bedeutet, dass Python jedes Mal, wenn ein Name verwendet wird, nach dem Objekt sucht, auf das es zeigt. Diese Dynamik ist einer der Hauptgründe, warum Python langsamer läuft als einige andere Sprachen. Die Dynamik von Python bietet große Flexibilität und Bequemlichkeit, geht jedoch zu Lasten der Laufzeitleistung.

Ein Vorteil von echten konstanten Deklarationen in Python wäre eine gewisse Verringerung der Häufigkeit von Objektsuchen, die zur Laufzeit stattfinden, und damit eine bessere Leistung. Wenn die Laufzeit im Voraus weiß, dass sich ein bestimmter Wert nie ändert, muss sie ihre Bindungen nicht nachschlagen. Dies könnte auch eine Möglichkeit für weitere Optimierungen von Drittanbietern bieten, z. B. Systeme, die maschineneigenen Code aus Python-Apps generieren (Cython, Nuitka).

Wahre Konstanten wären jedoch eine wesentliche Änderung und höchstwahrscheinlich eine rückwärts inkompatible Änderung. Es wäre auch umstritten, ob Konstanten durch eine neue Syntax - zum Beispiel das noch nicht verwendete  $ Symbol - oder als Erweiterung von Pythons bestehender Methode zur Deklaration von Namen kommen würden. Schließlich stellt sich die größere philosophische Frage, ob wahre Konstanten in einer Sprache, in der Dynamik einen großen Teil des Appells ausmacht, sinnvoll sind oder nicht.

Kurz gesagt, es ist möglich, dass wir in Python echte Konstanten sehen, aber es wäre eine große bahnbrechende Änderung.

Echte Überladung und Generika

In vielen Sprachen können mehrere Versionen derselben Funktion geschrieben werden, um mit verschiedenen Arten von Eingaben zu arbeiten. Zum Beispiel to_string() könnte eine  Funktion unterschiedliche Implementierungen für die Konvertierung von Ganzzahlen, Gleitkommazahlen oder anderen Objekten haben - sie würden jedoch der Einfachheit halber denselben Namen haben. "Überladen" oder "Generika" erleichtern das Schreiben robuster Software, da Sie generische Methoden für allgemeine Prozesse schreiben können, anstatt eine Methode speziell für einen bestimmten Typ zu verwenden.

Mit Python können Sie einen Funktionsnamen verwenden, der die Arbeit vieler erledigt, jedoch nicht, indem Sie mehrere Instanzen einer Funktion definieren. Sie können einen Namen in einem bestimmten Bereich nur einmal definieren und jeweils nur an ein einzelnes Objekt binden, sodass Sie nicht mehrere Versionen einer einzelnen Funktion unter demselben Namen haben können.

Um dies zu umgehen, verwenden Python-Entwickler normalerweise integrierte  Funktionen wie  isinstance() oder  type(), um den Typ der an eine Funktion gesendeten Variablen zu bestimmen, und ergreifen dann basierend auf dem Typ Maßnahmen. Manchmal beinhaltet dies den Versand an eine typspezifische Version einer Funktion unter der Haube. Dieser Ansatz macht es anderen Entwicklern jedoch schwer, Ihre Funktion zu erweitern, es sei denn, Sie geben sich alle Mühe, sie erweiterbar zu machen - beispielsweise durch Versenden an Methoden innerhalb einer Klasse, die in Unterklassen unterteilt werden könnten.

PEP 3124, das im April 2007 weiterentwickelt wurde, schlug einen Mechanismus zum Dekorieren von Funktionen vor, um anzuzeigen, dass sie überlastet werden könnten. Der Vorschlag wurde zurückgestellt und nicht sofort abgelehnt - was bedeutet, dass die Idee grundsätzlich solide war, aber der Zeitpunkt für die Umsetzung nicht richtig war. Ein Faktor, der die Übernahme von Überladung in Python beschleunigen oder dazu führen kann, dass die Idee vollständig verworfen wird, ist die Implementierung des neu vorgeschlagenen Mustervergleichssystems.

Theoretisch könnte der Mustervergleich unter der Haube verwendet werden, um den Überlastversand zu handhaben. Allerdings, Pattern - Matching auch als Begründung für gegeben werden konnte nicht Umsetzung Generika in Python, da es bereits eine elegante Möglichkeit zum Versand Operationen basierend auf Typen Signaturen zur Verfügung stellt.

So könnte es eines Tages zu einer echten Überladung in Python kommen, oder seine Vorteile könnten durch andere Mechanismen ersetzt werden.

Optimierungen der Schwanzrekursion

Viele Sprachcompiler verwenden Endrekursionsoptimierungen, bei denen Funktionen, die sich selbst aufrufen, keine neuen Stapelrahmen in der Anwendung erstellen und daher das Risiko eingehen, den Stapel in die Luft zu jagen, wenn sie zu lange ausgeführt werden. Python tut dies nicht, und tatsächlich haben sich seine Schöpfer konsequent dagegen ausgesprochen.

Ein Grund dafür ist, dass ein Großteil von Python von innen nach außen   eher Iteration als  Rekursion verwendet  - Generatoren, Coroutinen und so weiter. In diesem Fall bedeutet dies, dass anstelle eines rekursiven Mechanismus eine Funktion mit einer Schleife und einer Stapelstruktur verwendet wird. Jeder Aufruf der Schleife kann in einem Stapel gespeichert werden, um eine neue Rekursion zu erstellen, und nach Abschluss der Rekursion vom Stapel entfernt werden.

Python-Entwickler werden aufgefordert, diese Muster anstelle der Rekursion zu verwenden, sodass wenig Hoffnung auf Rekursionsoptimierungen besteht. Die Chancen hier sind überhaupt nicht wahrscheinlich, da Pythons Redewendungen andere Lösungen unterstützen.

Mehrzeilige Lambdas

Lambdas oder anonyme Funktionen schafften es erst nach einigem Widerstand des Sprachschöpfers Guido van Rossum in Python. Da Python-Lambdas jetzt existieren, sind sie stark eingeschränkt: Sie können nur einen einzelnen Ausdruck (im Wesentlichen alles rechts von einem Gleichheitszeichen in einer Zuweisungsoperation) als Funktionskörper verwenden. Wenn Sie einen vollständigen Block von Anweisungen wünschen, brechen Sie sie einfach aus und erstellen Sie daraus eine tatsächliche Funktion.

Der Grund liegt in der Gestaltung der Sprache, wie van Rossum sie sieht. Van Rossum schrieb 2006: „Ich finde  jede  Lösung inakzeptabel, die einen auf Einrückungen basierenden Block in die Mitte eines Ausdrucks einbettet. Da ich alternative Syntax für die Gruppierung von Anweisungen (z. B. geschweifte Klammern oder Schlüsselwörter für Anfang / Ende) ebenso inakzeptabel finde, macht dies ein mehrzeiliges Lambda zu einem unlösbaren Rätsel. “

Mit anderen Worten, das Problem ist nicht technisch, sondern das Fehlen einer Syntax für mehrzeilige Lambdas, die die bestehende Ästhetik der Python-Syntax ergänzt. Es gibt wahrscheinlich keine Möglichkeit, einen Sonderfall zu erstellen, und eine Sprache, die Sonderfälle enthält, wird in der Regel unangenehm. Bis ein solches Einhorn erscheint, müssen wir uns nur mit separat definierten Funktionen begnügen.

Mehrzeilige Lambdas kommen in Python wahrscheinlich nicht vor.

Lesen Sie mehr über Python:

  • Python 3.9: Was ist neu und besser?
  • Die besten neuen Funktionen in Python 3.8
  • Besseres Python-Projektmanagement mit Poetry
  • Virtualenv und venv: Erklärte virtuelle Python-Umgebungen
  • Python virtualenv und venv tun und nicht tun
  • Python-Threading und Unterprozesse erklärt
  • Verwendung des Python-Debuggers
  • Verwendung von timeit zum Profilieren von Python-Code
  • Verwendung von cProfile zum Profilieren von Python-Code
  • Beginnen Sie mit Async in Python
  • So verwenden Sie Asyncio in Python
  • So konvertieren Sie Python in JavaScript (und wieder zurück)
  • Python 2 EOL: Wie man das Ende von Python 2 überlebt
  • 12 Pythons für jeden Programmierbedarf
  • 24 Python-Bibliotheken für jeden Python-Entwickler
  • 7 süße Python-IDEs, die Sie vielleicht verpasst haben
  • 3 Hauptmängel von Python - und ihre Lösungen
  • 13 Python-Webframeworks verglichen
  • 4 Python-Test-Frameworks, um Ihre Fehler zu beseitigen
  • 6 großartige neue Python-Funktionen, die Sie nicht missen möchten
  • 5 Python-Distributionen zur Beherrschung des maschinellen Lernens
  • 8 großartige Python-Bibliotheken für die Verarbeitung natürlicher Sprache
  • 6 Python-Bibliotheken für die Parallelverarbeitung
  • Was ist PyPy? Schnelleres Python ohne Schmerzen
  • Was ist Cython? Python mit der Geschwindigkeit von C.