Following system colour scheme Selected dark colour scheme Selected light colour scheme

Python Enhancement Proposals

PEP 460 – Binäre Interpolation und Formatierung hinzufügen

Autor:
Antoine Pitrou <solipsis at pitrou.net>
Status:
Zurückgezogen
Typ:
Standards Track
Erstellt:
06-Jan-2014
Python-Version:
3.5

Inhaltsverzeichnis

Zusammenfassung

Dieses PEP schlägt vor, minimale Formatierungsoperationen zu den Objekten `bytes` und `bytearray` hinzuzufügen. Die vorgeschlagenen Ergänzungen sind

  • bytes % ... und bytearray % ... für die Prozentformatierung, ähnlich in der Syntax zur Prozentformatierung von str Objekten (Akzeptanz eines einzelnen Objekts, eines Tupels oder eines Diktats).
  • bytes.format(...) und bytearray.format(...) für eine Formatierung ähnlich in der Syntax zu str.format() (Akzeptanz von Positions- sowie Schlüsselwortargumenten).
  • bytes.format_map(...) und bytearray.format_map(...) für eine API ähnlich zu str.format_map(...), mit derselben Formatierungssyntax und Semantik wie bytes.format() und bytearray.format().

Begründung

In Python 2 erlauben str % args und str.format(args) die Formatierung und Interpolation von Bytestrings. Diese Funktion wurde häufig zum Zusammenstellen von Protokollnachrichten verwendet, wenn bekannt ist, dass Protokolle eine feste Kodierung verwenden.

Python 3 schreibt im Allgemeinen vor, dass Text als Unicode (d.h. str Objekte, nicht bytes) gespeichert und manipuliert wird. In einigen Fällen ist es jedoch sinnvoll, bytes Objekte direkt zu manipulieren. Typische Anwendungen sind binäre Netzwerkprotokolle, bei denen Sie mehrere Bytes-Objekte (einige davon Literale, einige davon berechnet) interpolieren und zusammensetzen möchten, um vollständige Protokollnachrichten zu erstellen. Protokolle wie HTTP oder SIP haben beispielsweise Header mit ASCII-Namen und undurchsichtige „textuelle“ Werte mit variabler und/oder manchmal schlecht definierter Kodierung. Darüber hinaus können diesen Headern ein binärer Körper folgen… der gechankt und mit ASCII-Headern und -Trailern verziert werden kann!

Obwohl es einigermaßen effiziente Möglichkeiten gibt, Binärdaten zu sammeln (wie z. B. die Verwendung eines bytearray Objekts, die Methode bytes.join oder sogar io.BytesIO), führt keine davon zu der Art von lesbarem und intuitivem Code, der durch eine %-formatierte oder {}-formatierte Vorlage und eine Formatierungsoperation erzeugt wird.

Binäre Formatierungsfunktionen

Unterstützte Funktionen

In diesem Vorschlag unterstützt die Prozentformatierung für bytes und bytearray die folgenden Funktionen

  • Nachschlagen von Formatierungsargumenten nach Position sowie nach Name (d.h. %s sowie %(name)s).
  • %s versucht, einen Py_buffer auf dem gegebenen Wert zu erhalten, und greift auf den Aufruf von __bytes__ zurück. Die resultierenden Binärdaten werden an der angegebenen Stelle in den String eingefügt. Dies sollte mit Bytes-, Bytearray- und Memoryview-Objekten (sowie einigen anderen wie pathlib’s Path-Objekten) funktionieren.
  • %c akzeptiert eine Ganzzahl zwischen 0 und 255 und fügt ein Byte des angegebenen Werts ein.

Die Klammerformatierung für bytes und bytearray unterstützt die folgenden Funktionen

  • Alle Arten von Argumentnachschlagen, die von str.format() unterstützt werden (explizites Positionsnachschlagen, automatisch inkrementiertes Positionsnachschlagen, Schlüsselwortnachschlagen, Attributnachschlagen usw.)
  • Einfügen von Binärdaten, wenn kein Modifikator oder Layout angegeben ist (z. B. {}, {0}, {name}). Dies hat dieselbe Semantik wie %s für die Prozentformatierung (siehe oben).
  • Der Modifikator c akzeptiert eine Ganzzahl zwischen 0 und 255 und fügt ein Byte des angegebenen Werts ein (dasselbe wie %c oben).

Nicht unterstützte Funktionen

Alle anderen Funktionen, die in der Formatierung von str Objekten vorhanden sind (entweder über den Prozentoperator oder die Methode str.format()), werden nicht unterstützt. Diese Funktionen implizieren, dass das Empfangsobjekt des Operators oder der Methode als Text behandelt wird, was der Trennung von Text/Bytes entgegensteht (z. B. würde die Akzeptanz von %d als Formatcode implizieren, dass das Bytes-Objekt tatsächlich eine ASCII-kompatible Textzeichenkette ist).

Zu diesen nicht unterstützten Funktionen gehören nicht nur die meisten typspezifischen Formatcodes, sondern auch die verschiedenen Layout-Spezifizierer wie Auffüllung oder Ausrichtung. Außerdem sind str Objekte keine akzeptablen Argumente für die Formatierungsoperationen, selbst bei Verwendung des Formatcodes %s.

__format__ wird nicht aufgerufen.

Kritik

  • Die Entwicklungskosten und die Wartungskosten.
  • In 3.3 ist die Kodierung nach ASCII oder Latin-1 so schnell wie memcpy (aber sie erstellt immer noch ein separates Objekt).
  • Entwickler müssen den Mangel an binärer Formatierung ohnehin umgehen, wenn sie Python 3.4 und früher unterstützen wollen.
  • bytes.join() ist durchgängig schneller als format zum Verbinden von Bytes-Strings (XXX *ist es?*).
  • Formatierungsfunktionen könnten in einem Drittmodul implementiert werden, anstatt in integrierten Typen hinzugefügt zu werden.

Andere Vorschläge

Ein neuer Datentyp

Es wurde vorgeschlagen, einen neuen Datentyp speziell für die „Netzwerkprogrammierung“ zu erstellen. Die Autoren dieses PEP sind der Meinung, dass dies kontraproduktiv ist. Python 3 hat bereits mehrere wichtige Typen für die Manipulation von Binärdaten: bytes, bytearray, memoryview, io.BytesIO.

Ein weiterer Typ würde die Dinge für Benutzer verwirrender machen und die Interoperabilität zwischen Bibliotheken erschweren (auch potenziell sub-optimal aufgrund der notwendigen Konvertierungen).

Darüber hinaus wäre nicht ein Typ erforderlich, sondern zwei: ein unveränderlicher Typ (um Hashing zu ermöglichen) und ein veränderlicher Typ (da effiziente Akkumulation oft notwendig ist, wenn mit Netzwerknachrichten gearbeitet wird).

Entscheidung

Dieses PEP wird durch die Annahme von PEP 461 obsolet, das eine erweiterte Formatierungssprache für Bytes-Objekte in Verbindung mit dem Modulo-Operator einführt.

Referenzen


Quelle: https://github.com/python/peps/blob/main/peps/pep-0460.rst

Zuletzt geändert: 2025-02-01 08:59:27 GMT