it-swarm.com.de

Was macht das Zeichen 'b' vor einem String-Literal?

Anscheinend ist die folgende Syntax gültig

my_string = b'The string'

Ich würde gerne wissen:

  1. Was bedeutet dieses b Zeichen vor dem String?
  2. Welche Auswirkungen hat die Verwendung?
  3. Was sind geeignete Situationen, um es zu verwenden?

Ich habe hier auf SO eine verwandte Frage gefunden, aber diese Frage handelt von PHP und besagt, dass b verwendet wird, um anzugeben, dass der String binär ist, wie Im Gegensatz zu Unicode, das für die Kompatibilität von Code mit der Version von PHP <6 bei der Migration auf PHP 6 erforderlich war. Ich glaube nicht, dass dies für Python gilt.

Ich habe diese Dokumentation auf der Site Python über die Verwendung eines Zeichens u in derselben Syntax gefunden, um eine Zeichenfolge als Unicode anzugeben. Leider wird das Zeichen b nirgendwo in diesem Dokument erwähnt.

Gibt es aus Neugier mehr Symbole als b und u, die andere Dinge tun?

668
Jesse Webb

So zitieren Sie die Python 2.x-Dokumentation :

Ein Präfix von 'b' oder 'B' wird in Python 2 ignoriert; Es gibt an, dass das Literal in Python 3 ein Byte-Literal werden soll (z. B. wenn Code automatisch mit 2to3 konvertiert wird). Auf ein 'u' oder 'b' Präfix kann ein 'r' Präfix folgen.

In der Python 3-Dokumentation heißt es:

Byte-Literale haben immer das Präfix 'b' oder 'B'. Sie erzeugen eine Instanz vom Typ bytes anstelle des Typs str. Sie dürfen nur ASCII Zeichen enthalten. Bytes mit einem numerischen Wert von 128 oder höher müssen mit Escape-Zeichen angegeben werden.

339
NPE

Python 3.x unterscheidet klar zwischen den Typen:

  • str = '...' Literale = eine Folge von Unicode-Zeichen (UTF-16 oder UTF-32, je nachdem, wie Python kompiliert wurde)
  • bytes = b'...' literals = eine Folge von Oktetten (ganze Zahlen zwischen 0 und 255)

Wenn Sie mit Java oder C # vertraut sind, stellen Sie sich str als String und bytes als byte[] vor. Wenn Sie mit SQL vertraut sind, stellen Sie sich str als NVARCHAR und bytes als BINARY oder BLOB vor. Wenn Sie mit der Windows-Registrierung vertraut sind, stellen Sie sich str als REG_SZ und bytes als REG_BINARY vor. Wenn Sie mit C (++) vertraut sind, vergessen Sie alles, was Sie über char und Strings gelernt haben, da A CHARACTER IS NOT A BYTE . Diese Idee ist längst überholt.

Sie verwenden str, wenn Sie Text darstellen möchten.

print('שלום עולם')

Sie verwenden bytes, wenn Sie einfache Binärdaten wie Strukturen darstellen möchten.

NaN = struct.unpack('>d', b'\xff\xf8\x00\x00\x00\x00\x00\x00')[0]

Sie können encode ein str zu einem bytes Objekt.

>>> '\uFEFF'.encode('UTF-8')
b'\xef\xbb\xbf'

Und Sie können einen bytes in einen str dekodieren.

>>> b'\xE2\x82\xAC'.decode('UTF-8')
'€'

Sie können die beiden Typen jedoch nicht frei mischen.

>>> b'\xEF\xBB\xBF' + 'Text with a UTF-8 BOM'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can't concat bytes to str

Die b'...' -Notation ist insofern etwas verwirrend, als die Bytes 0x01-0x7F mit ASCII Zeichen anstelle von Hex-Zahlen angegeben werden können.

>>> b'A' == b'\x41'
True

Aber ich muss betonen, ein Zeichen ist kein Byte .

>>> 'A' == b'A'
False

In Python 2.x

In Versionen vor Version 3.0 von Python fehlte diese Art der Unterscheidung zwischen Text- und Binärdaten. Stattdessen gab es:

  • unicode = u'...' Literale = Folge von Unicode-Zeichen = 3.x str
  • str = '...' literals = Folgen von verwirrten Bytes/Zeichen
    • Normalerweise Text, der in einer nicht festgelegten Codierung codiert ist.
    • Wird aber auch zur Darstellung von Binärdaten wie der Ausgabe von struct.pack verwendet.

Um den Übergang von 2.x zu 3.x zu vereinfachen, wurde die Literal-Syntax von b'...' auf Python 2.6 zurückportiert, um die Unterscheidung von Binärzeichenfolgen zu ermöglichen (die in 3 bytes sein sollten) .x) aus Textzeichenfolgen (die in 3.x str sein sollten). Das Präfix b bewirkt in 2.x nichts, weist jedoch das Script 2to3 an, es in 3.x nicht in eine Unicode-Zeichenfolge zu konvertieren.

Also ja, b'...' Literale in Python haben den gleichen Zweck wie in PHP.

Gibt es aus Neugier mehr Symbole als das b und u, die andere Dinge tun?

Das Präfix r erstellt eine Rohzeichenfolge (z. B. r'\t' ist ein umgekehrter Schrägstrich + t anstelle eines Tabulators), und dreifache Anführungszeichen '''...''' oder """...""" ermöglichen mehrzeilige Zeichenfolgenliterale.

560
dan04

Das b bezeichnet eine Bytekette.

Bytes sind die eigentlichen Daten. Strings sind eine Abstraktion.

Wenn Sie ein Zeichenfolgenobjekt mit mehreren Zeichen hätten und ein einzelnes Zeichen hätten, wäre dies eine Zeichenfolge, die abhängig von der Codierung möglicherweise mehr als 1 Byte groß ist.

Wenn Sie 1 Byte mit einer Byte-Zeichenfolge benötigen, erhalten Sie einen einzelnen 8-Bit-Wert von 0 bis 255, der möglicherweise kein vollständiges Zeichen darstellt, wenn diese Zeichen aufgrund der Codierung> 1 Byte waren.

TBH Ich würde Zeichenfolgen verwenden, es sei denn, ich hätte einen bestimmten Grund für die Verwendung von Bytes auf niedriger Ebene.

16
gecko

Wenn wir vom Server aus eine Antwort senden, wird diese in Form eines Bytetyps gesendet, sodass sie im Client als b'Response from server' angezeigt wird.

Um b'....' loszuwerden, verwenden Sie einfach den folgenden Code:

Serverdatei:

stri="Response from server"    
c.send(stri.encode())

Client-Datei:

print(s.recv(1024).decode())

dann wird es Response from server drucken

9
Nani Chintha

Es verwandelt es in ein bytes -Literal (oder str in 2.x) und ist ab 2.6 gültig.

Das r -Präfix bewirkt, dass Backslashes "nicht interpretiert" werden (nicht ignoriert, und der Unterschied ist wichtig).

Hier ist ein Beispiel, in dem das Fehlen von b eine TypeError -Ausnahme in Python 3.x auslöst

>>> f=open("new", "wb")
>>> f.write("Hello Python!")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' does not support the buffer interface

Das Hinzufügen eines b -Präfixes würde das Problem beheben.

8
user3053230

Beachten Sie außerdem, dass ein einzelnes Zeichen in Unicode aus mehreren Bytes bestehen kann.

Die Art und Weise, wie Unicode funktioniert, ist, dass es das alte ASCII -Format (7-Bit-Code, der wie 0xxx xxxx aussieht) verwendet und Multibyte-Sequenzen hinzugefügt hat, wobei alle Bytes mit 1 (1xxx) beginnen xxxx), um Zeichen jenseits von ASCII darzustellen, damit Unicode abwärtskompatibel mit ASCII wäre.

>>> len('Öl')  # German Word for 'oil' with 2 characters
2
>>> 'Öl'.encode('UTF-8')  # convert str to bytes 
b'\xc3\x96l'
>>> len('Öl'.encode('UTF-8'))  # 3 bytes encode 2 characters !
3
2
xjcl

Sie können JSON verwenden, um es in ein Wörterbuch zu konvertieren

import json
data = b'{"key":"value"}'
print(json.loads(data))

{"Schlüsselwert"}


FLASCHE:

Dies ist ein Beispiel aus der Flasche. Führen Sie dies am Terminal aus:

import requests
requests.post(url='http://localhost(example)/',json={'key':'value'})

In der Flasche/routes.py

@app.route('/', methods=['POST'])
def api_script_add():
    print(request.data) # --> b'{"hi":"Hello"}'
    print(json.loads(request.data))
return json.loads(request.data)

{'Schlüsselwert'}

0
Karam Qusai