Cosa fa il carattere "b" davanti a una stringa letterale?


832

Apparentemente, la seguente è la sintassi valida:

my_string = b'The string'

Mi piacerebbe sapere:

  1. Cosa significa questo bcarattere davanti alla stringa?
  2. Quali sono gli effetti del suo utilizzo?
  3. Quali sono le situazioni appropriate per usarlo?

Ho trovato una domanda correlata proprio qui su SO, ma quella domanda riguarda PHP, e afferma che bè usato per indicare che la stringa è binaria, al contrario di Unicode, che era necessario affinché il codice fosse compatibile dalla versione di PHP <6 , durante la migrazione a PHP 6. Non credo che ciò si applichi a Python.

Ho trovato questa documentazione sul sito di Python sull'uso di un upersonaggio nella stessa sintassi per specificare una stringa come Unicode. Sfortunatamente, non menziona il carattere b da nessuna parte in quel documento.

Inoltre, solo per curiosità, ci sono più simboli di be uche fanno altre cose?

Risposte:


417

Per citare la documentazione di Python 2.x :

Un prefisso di "b" o "B" viene ignorato in Python 2; indica che il valore letterale dovrebbe diventare un valore letterale di byte in Python 3 (ad es. quando il codice viene convertito automaticamente con 2to3). Un prefisso 'u' o 'b' può essere seguito da un prefisso 'r'.

La documentazione di Python 3 afferma:

I byte letterali sono sempre preceduti da "b" o "B"; producono un'istanza del tipo di byte anziché del tipo str. Possono contenere solo caratteri ASCII; i byte con un valore numerico di 128 o superiore devono essere espressi con escape.


4
Quindi sembra che Python <v3 ignorerà questo personaggio in più. Cosa sarebbe un caso in v3 in cui avresti bisogno di usare una stringa ab invece di una normale stringa?
Jesse Webb,

5
@Gweebz - se stai effettivamente digitando una stringa in una particolare codifica anziché con escape unicode (ad es. B '\ xff \ xfe \ xe12' invece di '\ u32e1').
detenere l'

7
In realtà, se hai importato unicode_literalsda __future__, questo "inverte" il comportamento di questa particolare stringa (in Python 2.x)
Romuald Brunet

34
Un po 'di narrativa in linguaggio più semplice intorno alla documentazione citata renderebbe questa una risposta migliore IMHO
Hack-R

2
Altrimenti, è una risposta per qualcuno che già lo capisce.
Rafael Eyng,

681

Python 3.x fa una chiara distinzione tra i tipi:

  • str= '...'valori letterali = una sequenza di caratteri Unicode (UTF-16 o UTF-32, a seconda di come è stato compilato Python)
  • bytes= b'...'valori letterali = una sequenza di ottetti (numeri interi compresi tra 0 e 255)

Se hai familiarità con Java o C #, pensa a strcome Stringe bytescome byte[]. Se hai familiarità con SQL, pensa a strcome NVARCHARe bytescome BINARYo BLOB. Se hai familiarità con il registro di Windows, pensa a strcome REG_SZe bytescome REG_BINARY. Se hai familiarità con C (++), allora dimentica tutto ciò che hai appreso chare le stringhe, perché UN PERSONAGGIO NON È UN BYTE . Quell'idea è da lungo tempo obsoleta.

Si utilizza strquando si desidera rappresentare il testo.

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

Si utilizza bytesquando si desidera rappresentare dati binari di basso livello come le strutture.

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

È possibile codificare a strin un bytesoggetto.

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

E puoi decodificare a bytesin a str.

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

Ma non puoi mescolare liberamente i due tipi.

>>> 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

La b'...'notazione è alquanto confusa in quanto consente di specificare i byte 0x01-0x7F con caratteri ASCII anziché numeri esadecimali.

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

Ma devo sottolineare, un personaggio non è un byte .

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

In Python 2.x

Le versioni pre-3.0 di Python mancavano di questo tipo di distinzione tra testo e dati binari. Invece, c'era:

  • unicode= u'...'valori letterali = sequenza di caratteri Unicode = 3.xstr
  • str = '...' valori letterali = sequenze di byte / caratteri confusi
    • Di solito testo, codificato in una codifica non specificata.
    • Ma usato anche per rappresentare dati binari come l' struct.packoutput.

Per facilitare la transizione da 2.x-a-3.x, la b'...'sintassi letterale è stata importata in Python 2.6, al fine di consentire di distinguere le stringhe binarie (che dovrebbero essere bytesin 3.x) dalle stringhe di testo (che dovrebbero essere strin 3 .X). Il bprefisso non fa nulla in 2.x, ma dice allo 2to3script di non convertirlo in una stringa Unicode in 3.x.

Quindi sì, i b'...'letterali in Python hanno lo stesso scopo che hanno in PHP.

Inoltre, solo per curiosità, ci sono più simboli di b e u che fanno altre cose?

Il rprefisso crea una stringa non elaborata (ad esempio, r'\t'è una barra rovesciata + tanziché una scheda) e tripla virgolette '''...'''o """..."""consente letterali stringa a più righe.


2
Grazie! L'ho capito dopo aver letto queste frasi: "Per facilitare la transizione da 2.x-a-3.x, la sintassi letterale b '...' è stata riportata in Python 2.6, al fine di consentire di distinguere le stringhe binarie (che dovrebbero essere byte in 3.x) dalle stringhe di testo (che dovrebbero essere str in 3.x). Il prefisso b non fa nulla in 2.x, ma dice allo script 2to3 di non convertirlo in una stringa Unicode in 3.x. "
tommy.carstensen,

4
Il 'A' == b'A' --> Falsecontrollo lo rende davvero chiaro. Il resto è eccellente, ma fino a quel momento non avevo capito bene che una stringa di byte non
Carattere jolly

12
'שלום עולם' == 'hello world'
Eli,

13
Questo è molto più chiaro della risposta accettata che sta semplicemente citando la documentazione. La documentazione per me non aveva senso, quindi fornire ulteriore contesto nella documentazione è fantastico. Grazie!
Rayryeng,

3
b "some string" .decode ('UTF-8'), credo che sia la linea che molti stanno cercando
Marvin Thobejane,

23

La b indica una stringa di byte.

I byte sono i dati effettivi. Le stringhe sono un'astrazione.

Se avessi un oggetto stringa multi-carattere e prendessi un singolo carattere, sarebbe una stringa e potrebbe avere una dimensione superiore a 1 byte a seconda della codifica.

Se prendessi 1 byte con una stringa di byte, otterrai un singolo valore di 8 bit da 0 a 255 e potrebbe non rappresentare un carattere completo se quei caratteri dovuti alla codifica fossero> 1 byte.

TBH userei le stringhe a meno che non avessi qualche motivo specifico di basso livello per usare i byte.


16

Dal lato server, se inviamo una risposta, verrà inviata sotto forma di tipo byte, quindi apparirà nel client come b'Response from server'

Per sbarazzarsi di b'....'usare semplicemente il codice qui sotto:

File del server:

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

File client:

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

quindi stamperà Response from server


1
Non spiega la domanda che Jesse Webb ha posto!
Chandra Kanth,

Stavo dicendo che senza usare i metodi di codifica e decodifica, l'output della stringa sarà preceduto da b '' come python lo prende come un tipo di byte anziché come tipo di stringa.Se non vuoi ottenere un output come b '... "usa quanto sopra. Ecco cosa non hai capito?
Nani Chintha,

In realtà questa è esattamente la risposta al titolo della domanda che è stata posta: D: "Cosa fa b'x '?" A: "Fa 'x'.encode ()" Questo è letteralmente quello che fa. Il resto della domanda voleva sapere molto più di questo, ma al titolo viene data risposta.
Michael Erickson,

10

Ecco un esempio in cui l'assenza di bavrebbe generato TypeErrorun'eccezione in Python 3.x

>>> 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

L'aggiunta di un bprefisso risolverebbe il problema.


9

Lo trasforma in un bytesletterale (ostr in 2.x) ed è valido per 2.6+.

Il rprefisso fa sì che le barre rovesciate da "non interpretati" (non ignorato, e la differenza non importa).


Questo sembra sbagliato secondo la documentazione citata nella risposta di aix; la b verrà ignorata nella versione Python diversa da 3.
Jesse Webb,

2
Sarà un strin 2.x in entrambi i modi, quindi si potrebbe dire che viene ignorato. La distinzione è importante quando si importa unicode_literalsdal __future__modulo.
Ignacio Vazquez-Abrams,

6

Oltre a ciò che altri hanno detto, nota che un singolo carattere in Unicode può essere composto da più byte .

Il modo in cui funziona Unicode è che ha impiegato il vecchio formato ASCII (codice a 7 bit che assomiglia a 0xxx xxxx) e ha aggiunto sequenze multi-byte in cui tutti i byte iniziano con 1 (1xxx xxxx) per rappresentare i caratteri oltre ASCII in modo che Unicode sia indietro -compatibile con ASCII.

>>> 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

È possibile utilizzare JSON per convertirlo in dizionario

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

{ "Chiave": "valore"}


BORRACCIA:

Questo è un esempio di pallone. Esegui questo sulla linea terminale:

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

In boccetta / route.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)

{ 'Chiave': 'valore'}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.