byte vs array di byte in Python 2.6 e 3
-
20-09-2019 - |
Domanda
Sto sperimentando bytes
contro bytearray
in Python 2.6.Non capisco il motivo di alcune differenze.
UN bytes
l'iteratore restituisce stringhe:
for i in bytes(b"hi"):
print(type(i))
Dà:
<type 'str'>
<type 'str'>
Ma a bytearray
l'iteratore ritorna int
S:
for i in bytearray(b"hi"):
print(type(i))
Dà:
<type 'int'>
<type 'int'>
Perché la differenza?
Mi piacerebbe scrivere codice che si tradurrà bene in Python 3.Quindi, la situazione è la stessa in Python 3?
Soluzione
In Python 2.6 byte è semplicemente un alias per str .
Questo "tipo pseudo" è stata introdotta per [parzialmente] preparare programmi [e programmatori!] Da convertire / compatibile con Python 3.0 in cui v'è una rigorosa distinzione di semantica e uso per str (che sono sistematicamente unicode) e byte (che sono array di ottetti, per memorizzare i dati, ma non il testo)
Allo stesso modo il prefisso b per stringhe è inefficace in 2.6, ma è un indicatore utile nel programma, che le bandiere in modo esplicito l'intento del programmatore per avere la stringa come una stringa di dati, piuttosto che una stringa di testo. Questa informazione può quindi essere utilizzato dal convertitore 2to3 o utility simili quando il programma è stato portato su Py3k.
Si consiglia di controllare questo domanda SO Per ulteriori informazioni.
Altri suggerimenti
Per (almeno) Python 3.7
oggetti
bytes
sono sequenze immutabili dei singoli bytesoggetti
bytearray
sono una controparte mutevole di byte oggetti.
E questo è più o meno il più lontano bytes
vs bytearray
. In effetti, sono abbastanza intercambiabili e progettato per sufficientemente flessibile da miscelare in operazioni senza gettare errori. In realtà, v'è un'intera sezione nel documentazione ufficiale dedicato a mostrare le somiglianze tra le bytes
e bytearray
apis.
Alcuni indizi utili a capire il motivo per cui dalla documentazione:
Poiché molte importanti protocolli binari sono basati sulla codifica di testo ASCII, byte oggetti offrono diversi metodi che sono valide solo quando si lavora con dati compatibili ASCII e sono strettamente legati agli oggetti stringa in una varietà di altri modi.
TL;DR
python2.6+
bytes
= pitone2.6+str
= python3.xbytes
!= python3.xstr
python2.6+
bytearray
= python3.xbytearray
python2.x
unicode
= python3.xstr
Risposta lunga
bytes
E str
hanno cambiato significato in Python da Python 3.x.
Prima di rispondere brevemente alla tua domanda, in Python 2.6 bytes(b"hi")
è un array immutabile di byte (8 bit o ottetti).Quindi il tipo di ciascuno byte
è semplicemente byte
, che è lo stesso di str
in Python 2.6+ (tuttavia, questo non è il caso in Python 3.x)
bytearray(b"hi")
è ancora una volta un array mutabile di byte.Ma quando chiedi il suo tipo, è un int
, perché Python rappresenta ogni elemento di bytearray
come numero intero compreso tra 0 e 255 (tutti i valori possibili per un numero intero a 8 bit).Tuttavia, un elemento di bytes
l'array è rappresentato come un valore ASCII di quel byte.
Consideriamo ad esempio in Python 2.6+
>>> barr=bytearray(b'hi')
>>> bs=bytes(b'hi')
>>> barr[0] # python shows you an int value for the 8 bits 0110 1000
104
>>> bs[0] # python shows you an ASCII value for the 8 bits 0110 1000
'h'
>>> chr(barr[0]) # chr converts 104 to its corresponding ASCII value
'h'
>>> bs[0]==chr(barr[0]) # python compares ASCII value of 1st byte of bs and ASCII value of integer represented by first byte of barr
True
Ora Python 3.x è una storia completamente diversa.Come potresti aver sospettato, è strano il motivo per cui un str
letterale significherebbe a byte
in Python2.6+.BENE questa risposta lo spiega
In Python 3.x, un str
è un testo Unicode (che in precedenza era solo un array di byte, nota che Unicode e byte sono due cose completamente diverse). bytearray
è un mutevole array di byte mentre bytes
è un immutabile matrice di byte.Entrambi hanno quasi le stesse funzioni.Ora, se eseguo nuovamente lo stesso codice sopra in Python 3.x, ecco il risultato.In Python 3.x
>>> barr=bytearray(b'hi')
>>> bs=bytes(b'hi')
>>> barr[0]
104
>>> bs[0]
104
>>> bs[0]==barr[0] # bytes and bytearray are same thing in python 3.x
True
bytes
E bytearray
sono le stesse cose in Python 3.x, tranne che per la mutabilità.
cos'è successo a str
potresti chiedere? str
in Python 3 è stato convertito in what unicode
era in Python 2 e unicode
type è stato successivamente rimosso da Python 3 poiché ridondante.
Mi piacerebbe scrivere codice che si tradurrà bene in Python 3.Quindi, la situazione è la stessa in Python 3?
Dipende da cosa stai cercando di fare.Hai a che fare con byte o hai a che fare con la rappresentazione ASCII dei byte?
Se hai a che fare con byte, allora il mio consiglio è di usare bytearray
in Python 2, che è lo stesso in Python 3.Ma perdi l'immutabilità, se questo ti interessa.
Se hai a che fare con ASCII o text, quindi rappresenta la stringa come u'hi'
in Python 2, che ha lo stesso significato in Python 3. 'u'
ha un significato speciale in Python 2, che indica a Python 2 di trattare una stringa letterale come unicode
tipo.'u' in Python 3 non ha significato, perché tutte le stringhe letterali in Python 3 sono Unicode per impostazione predefinita (che viene chiamato in modo confuso str
digita Python 3 e unicode
digitare Python 2).
Non sono sicuro dal quale versione, ma bytes
è in realtà un str
, che si può vedere se si fa type(bytes(b"hi"))
-.> <type 'str'>
bytearray
è una matrice mutevole di byte, un costruttore di che prende una stringa.
ho provato su Python 3.0.
In Python 3.0, un iteratore bytes
restituisce int
s, non stringhe come ha fatto Python 2.6:
for i in bytes(b"hi"):
print(type(i))
si ottiene:
<class 'int'>
<class 'int'>
Un iteratore bytearray
restituisce anche class 'int'
s.