Come convertire i byte in stringhe in Python 2 e Python 3

  1. Convertire i Byte in Stringa in Python 2.x
  2. Convertire Bytes in Stringa in Python 3.x
  3. Confronto delle prestazioni e conclusione dei diversi metodi di conversione dei byte in una stringa

Questo articolo del tutorial introdurrà come convertire i bytes in stringhe in Python 2.x e Python 3.x.

Convertire i Byte in Stringa in Python 2.x

bytes in Python 2.7 è identica a str, quindi la variabile iniziata come bytes è la stringa intrinsecamente.

Python 2.7.10 (default, May 23 2015, 09:44:00) [MSC v.1500 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> A = b'cd'
>>> A
'cd'
>>> type(A)
<type 'str'>

Convertire Bytes in Stringa in Python 3.x

bytes è un nuovo tipo di dati introdotto in Python 3.

Python 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 18:11:49) [MSC v.1900 64 bit (AMD64)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> A = b'cd'
>>> A
b'cd'
>>> type(A)
<class 'bytes'>
>>> 

Il tipo di dati degli elementi nei bytes è int.

>>> A = b'cd'
>>> A[0]
99
>>> type(A[0])
<class 'int'>

Convertire Bytes in Stringa usando decode in Python 3.x

Il metodo .decode di bytes potrebbe convertire i byte in stringhe con il metodo encoding dato. Va bene nella maggior parte dei casi se si lascia il metodo encoding come predefinito utf-8, ma non è sempre sicuro perché i byte potrebbero essere codificati con un altro metodo di codifica piuttosto che utf-8.

>>> b'\x50\x51'.decode()
'PQ'
>>> b'\x50\x51'.decode('utf-8')
'PQ'
>>> b'\x50\x51'.decode(encoding = 'utf-8')
'PQ'

I tre modi per decodificare i byte come mostrato sopra sono identici perché utf-8 è usato come metodo di codifica.

Potrebbe generare errori quando si usa utf-8 ma i byte non sono codificati con esso.

>>> b'\x50\x51\xffed'.decode('utf-8')
Traceback (most recent call last):
  File "<pyshell#16>", line 1, in <module>
    b'\x50\x51\xffed'.decode('utf-8')
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 2: invalid start byte

Otteniamo il UnicodeDecodeError che dice utf-8 non è il giusto codec.

Abbiamo due approcci per risolvere questo problema di “codifica”.

backslashreplace, ignore o sostituire come parametri di errors

Il decode ha l’altro parametro oltre alla encoding - “errors”. Esso definisce il comportamento quando si verifica un error. Il valore di default di errors è strict, il che significa che solleva un errore se l’errore si verifica nel processo di decodifica.

error ha altre opzioni come ignore, replace o altri nomi registrati codecs.register_error, backslashreplace per esempio.

ignore ignora gli errori di decodifica sbagliati e crea la stringa di output come può.

replace sostituisce i caratteri corrispondenti con i caratteri definiti nel metodo di encoding come indicato. backslashreplace sostituisce i caratteri che non potevano essere decodificati con lo stesso contenuto dei bytes originali.

>>> b'\x50\x51\xffed'.decode('utf-8', 'backslashreplace')
'PQ\\xffed'
>>> b'\x50\x51\xffed'.decode('utf-8', 'ignore')
'PQed'
>>> b'\x50\x51\xffed'.decode('utf-8', 'replace')
'PQ�ed'

La codifica MS-DOS cp437 potrebbe essere usata se la codifica dei dati bytes è sconosciuta.

>>> b'\x50\x51\xffed'.decode('cp437')
'PQ\xa0ed'

chr per convertire i byte in stringhe in Python 3.x

chr(i, /) restituisce una stringa Unicode di un carattere con ordinale. Potrebbe convertire l’elemento di bytes in una string ma non il bytes completo.

Potremmo usare la comprensione di liste o la map per ottenere la stringa convertita di bytes mentre utilizziamo chr per il singolo elemento.

>>> A =  b'\x50\x51\x52\x53'
>>> "".join([chr(_) for _ in A])
'PQRS'
>>> "".join(map(chr, A))
'PQRS'

Confronto delle prestazioni e conclusione dei diversi metodi di conversione dei byte in una stringa

Usiamo timeit per confrontare le prestazioni del metodo introdotto in questo tutorial - decode e chr.

>>> import timeit
>>> timeit.timeit('b"\x50\x51\x52\x53".decode()', number=1000000)
0.1356779
>>> timeit.timeit('"".join(map(chr, b"\x50\x51\x52\x53"))', number=1000000)
0.8295201999999975
>>> timeit.timeit('"".join([chr(_) for _ in b"\x50\x51\x52\x53"])', number=1000000)
0.9530071000000362

Si può vedere dalle prestazioni di timeit sopra mostrate, decode() è molto più veloce e chr() è relativamente inefficiente perché ha bisogno di ricostruire la stringa a partire dal carattere della singola stringa.

Si consiglia di usare decode nell’applicazione critica per le prestazioni.

Articolo correlato - Python Bytes

  • Converti Int in binario in Python
  • Articolo correlato - Python Encoding-Decoding

  • Converti byte in esadecimale in Python
  • Articolo correlato - Python String

  • Converti byte in esadecimale in Python
  • Converti una stringa in nome variabile in Python