TypeError: 'str' unterstützt die Puffer-Schnittstelle nicht schlägt zwei mögliche Methoden vor, einen String in Bytes zu konvertieren:
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
Welche Methode ist pythonischer?
TypeError: 'str' unterstützt die Puffer-Schnittstelle nicht schlägt zwei mögliche Methoden vor, einen String in Bytes zu konvertieren:
b = bytes(mystring, 'utf-8')
b = mystring.encode('utf-8')
Welche Methode ist pythonischer?
Wenn Sie sich die Dokumentation für bytes
ansehen, wird Ihnen bytearray
angezeigt:
bytearray([quelle[, codierung[, fehler]]])
Geben Sie ein neues Array von Bytes zurück. Der ByteArray-Typ ist eine veränderliche Sequenz von Ganzzahlen im Bereich 0 <= x < 256. Es verfügt über die meisten üblichen Methoden veränderlicher Sequenzen, die in Veränderliche Sequenztypen beschrieben sind, sowie die meisten Methoden, die der Bytes-Typ hat, siehe Byte- und Byte-Array-Methoden.
Der optionale Quellenparameter kann verwendet werden, um das Array auf einige verschiedene Arten zu initialisieren:
Wenn es sich um einen String handelt, müssen Sie auch die Codierung (und optional die Fehler) Parameter angeben; bytearray() konvertiert dann den String in Bytes mit str.encode().
Wenn es sich um eine Ganzzahl handelt, hat das Array diese Größe und wird mit Null-Bytes initialisiert.
Wenn es sich um ein Objekt handelt, das der Puffer-Schnittstelle entspricht, wird ein schreibgeschützter Puffer des Objekts verwendet, um das Byte-Array zu initialisieren.
Wenn es sich um ein Iterable handelt, muss es ein Iterable von Ganzzahlen im Bereich 0 <= x < 256 sein, die als anfänglicher Inhalt des Arrays verwendet werden.
Ohne Argument wird ein Array der Größe 0 erstellt.
Also kann bytes
viel mehr als nur einen String codieren. Es ist Pythonisch, dass es Ihnen erlauben würde, den Konstruktor mit jedem Typ eines sinnvollen Quellenparameters aufzurufen.
Für das Codieren eines Strings denke ich, dass some_string.encode(encoding)
Pythonischer ist als die Verwendung des Konstruktors, weil es am selbsterklärendsten ist - "Nimm diesen String und verschlüssle ihn mit dieser Codierung" ist klarer als bytes(some_string, encoding)
- es gibt kein explizites Verb, wenn Sie den Konstruktor verwenden.
Ich habe den Python-Quellcode überprüft. Wenn Sie einen Unicode-String an bytes
in CPython übergeben, wird PyUnicode_AsEncodedString aufgerufen, was die Implementierung von encode
ist; Sie überspringen also nur eine Ebene der Indirektion, wenn Sie encode
selbst aufrufen.
Sehen Sie sich auch den Kommentar von Serdalis an - unicode_string.encode(encoding)
ist auch Pythonischer, weil sein Gegenteil byte_string.decode(encoding)
ist und Symmetrie schön ist.
Es ist einfacher als gedacht:
my_str = "hello world"
my_str_as_bytes = str.encode(my_str)
print(type(my_str_as_bytes)) # Stellen Sie sicher, dass es eine Byte-Repräsentation ist
my_decoded_str = my_str_as_bytes.decode()
print(type(my_decoded_str)) # Stellen Sie sicher, dass es eine String-Repräsentation ist
Sie können dies überprüfen, indem Sie die Typen ausgeben. Siehe Ausgabe unten.
Der absolut beste Weg ist nicht einer von beiden, sondern der dritte. Der erste Parameter für encode
ist standardmäßig auf 'utf-8'
gesetzt seit Python 3.0. Daher ist der beste Weg
b = mystring.encode()
Dies wird auch schneller sein, da das Standardargument nicht im C-Code zu dem String "utf-8"
führt, sondern zu NULL
, was viel schneller zu überprüfen ist!
Hier sind einige Zeitmessungen:
In [1]: %timeit -r 10 'abc'.encode('utf-8')
Der langsamste Durchlauf dauerte 38,07-mal länger als der schnellste.
Dies könnte bedeuten, dass ein Zwischenergebnis zwischengespeichert wird.
10000000 Durchläufe, bestes von 10: 183 ns pro Durchlauf
In [2]: %timeit -r 10 'abc'.encode()
Der langsamste Durchlauf dauerte 27,34-mal länger als der schnellste.
Dies könnte bedeuten, dass ein Zwischenergebnis zwischengespeichert wird.
10000000 Durchläufe, bestes von 10: 137 ns pro Durchlauf
Trotz der Warnung waren die Zeiten nach wiederholten Durchläufen sehr stabil - die Abweichung betrug nur ~2 Prozent.
Die Verwendung von encode()
ohne Argument ist nicht Python 2 kompatibel, da in Python 2 die Standard-Zeichenkodierung ASCII ist.
>>> 'äöä'.encode()
Traceback (most recent call last):
File "", line 1, in
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)
Antwort für ein etwas anderes Problem:
Sie haben eine Sequenz von Rohunicode, die in eine str-Variable gespeichert wurde:
s_str: str = "\x00\x01\x00\xc0\x01\x00\x00\x00\x04"
Sie müssen in der Lage sein, das Byte-Literal dieser Unicode zu erhalten (für struct.unpack(), etc.)
s_bytes: bytes = b'\x00\x01\x00\xc0\x01\x00\x00\x00\x04'
Lösung:
s_new: bytes = bytes(s, encoding="raw_unicode_escape")
Referenz (nach oben scrollen für Standardcodierungen):
Wie wäre es mit dem Python 3 'memoryview' Weg.
Memoryview ist eine Art Mischung aus den Modulen byte/bytearray und struct, mit mehreren Vorteilen.
Einfachstes Beispiel, für ein Byte-Array:
memoryview(b"some bytes").tolist()
[115, 111, 109, 101, 32, 98, 121, 116, 101, 115]
Oder für einen Unicode-String (der in ein Byte-Array umgewandelt wird)
memoryview(bytes("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020", "UTF-16")).tolist()
[255, 254, 117, 0, 110, 0, 105, 0, 99, 0, 111, 0, 100, 0, 101, 0, 32, 0]
#Eine andere Möglichkeit, das gleiche zu tun
memoryview("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020".encode("UTF-16")).tolist()
[255, 254, 117, 0, 110, 0, 105, 0, 99, 0, 111, 0, 100, 0, 101, 0, 32, 0]
Vielleicht benötigen Sie Wörter anstelle von Bytes?
memoryview(bytes("\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020", "UTF-16")).cast("H").tolist()
[65279, 117, 110, 105, 99, 111, 100, 101, 32]
memoryview(b"some more data").cast("L").tolist()
[1701670771, 1869422624, 538994034, 1635017060]
Vorsichtsmaßnahme. Seien Sie vorsichtig bei mehrdeutigen Byte-Reihenfolgen mit Daten von mehr als einem Byte:
txt = "\u0075\u006e\u0069\u0063\u006f\u0064\u0065\u0020"
for order in ("", "BE", "LE"):
mv = memoryview(bytes(txt, f"UTF-16{order}"))
print(mv.cast("H").tolist())
[65279, 117, 110, 105, 99, 111, 100, 101, 32]
[29952, 28160, 26880, 25344, 28416, 25600, 25856, 8192]
[117, 110, 105, 99, 111, 100, 101, 32]
Nicht sicher, ob das beabsichtigt ist oder ein Bug, hat mich aber erwischt!!
Das Beispiel verwendet UTF-16, für eine vollständige Liste der Codecs siehe Codec-Registry in Python 3.10
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.