Question

J'expérimente avec bytes vs bytearray en Python 2.6. Je ne comprends pas la raison de quelques différences.

iterator bytes renvoie des chaînes:

for i in bytes(b"hi"):
    print(type(i))

donne:

<type 'str'>
<type 'str'>

Mais un iterator bytearray retourne ints:

for i in bytearray(b"hi"):
    print(type(i))

donne:

<type 'int'>
<type 'int'>

Pourquoi la différence?

Je voudrais écrire un code qui se traduira bien en Python 3. Alors, est-ce la même chose en Python 3?

Était-ce utile?

La solution

En Python 2.6 octets est simplement un alias pour str .
Ce type « pseudo » a été présenté à [partiellement] préparer des programmes [et programmeurs!] À convertir / compatible avec Python 3.0 où il y a une distinction stricte de la sémantique et l'utilisation pour str (qui sont systématiquement unicode) et octets (qui sont des tableaux d'octets, pour stocker des données, mais pas de texte)

De même, le préfixe b pour littéraux de chaîne est inefficace en 2.6, mais il est un marqueur utile dans le programme, qui drapeaux explicitement l'intention du programmeur d'avoir la chaîne comme une chaîne de données plutôt que d'une chaîne de texte. Cette information peut alors être utilisé par le convertisseur de 2to3 ou utilitaires similaires lorsque le programme est porté à Py3K.

Vous pouvez consulter cette question SO pour des informations supplémentaires.

Autres conseils

A (au moins) Python 3.7

Selon les docs:

  

objets bytes sont des séquences d'octets uniques immuables

     

objets bytearray sont un homologue de mutable octets objets.

Et c'est à peu près aussi loin que bytes vs bytearray. En fait, ils sont assez interchangeables et conçu pour être suffisamment souple pour mélanger dans des opérations sans jeter des erreurs. En fait, il y a toute une section dans le documentation officielle dédié à montrer les similitudes entre les apis bytes et bytearray.

Quelques indices pour expliquer pourquoi des docs:

  

Étant donné que de nombreux grands protocoles binaires sont basés sur le codage de texte ASCII, octets objets offrent plusieurs méthodes qui ne sont valables que lorsque vous travaillez avec des données compatibles ASCII et sont étroitement liés à des objets de chaîne dans une variété d'autres façons.

TL; DR

  

python2.6 + bytes = python2.6 + str = python3.x bytes! = Python3.x str

     

python2.6 + bytearray = python3.x bytearray

     

python2.X unicode = python3.x str

Réponse longue

bytes et str ont changé de sens en python depuis python 3.x.

Tout d'abord répondre à votre question peu , en python 2.6 bytes(b"hi") est un tableau immuable d'octets (8 bits ou octets). Ainsi, le type de chaque byte est tout simplement byte, qui est le même que str en python 2.6+ (Cependant, ce n'est pas le cas dans 3.x python)

bytearray(b"hi") est à nouveau un tableau mutable d'octets. Mais quand vous demandez son type, c'est un int, parce que python représente chaque élément de bytearray comme un entier dans la gamme 0-255 (toutes les valeurs possibles pour un entier 8 bits). Cependant, un élément de réseau de bytes est représenté comme une valeur ASCII de cet octet.

Par exemple, considérons 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

3.x python est une toute autre histoire. Comme vous pouvez vous en douter, il est bizarre pourquoi un littéral str signifierait un byte dans python2.6 +. Eh bien cette réponse explique que

Dans 3.x Python, un str est un texte Unicode (ce qui était auparavant un simple tableau d'octets, notez que Unicode et octets sont deux choses complètement différentes). bytearray est un mutable array d'octets en bytes est un tableau d'octets immuable . Ils ont tous les deux à peu près les mêmes fonctions. Maintenant, si je lance à nouveau le même code ci-dessus dans 3.x python, voici le résultat. 3.x Python

>>> 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 et bytearray sont les mêmes choses 3.x python, sauf pour y mutabilité.

Qu'est-ce qui est arrivé à str vous pourriez demander? str en python 3 se convertit à ce que unicode était en python 2 et le type de unicode a ensuite été retiré de Python 3 comme il était redondant.

  

Je voudrais écrire un code qui se traduira bien en Python 3. Alors, est-ce la même chose en Python 3?

Cela dépend de ce que vous essayez de faire. Est-ce que vous traitez avec des octets ou vous traitez avec une représentation ASCII d'octets?

Si vous traitez avec des octets , mon conseil est d'utiliser bytearray en Python 2, qui est le même en python 3. Mais vous immuabilité lâche, si cette question vous.

Si vous traitez avec ASCII ou texte , puis représenter votre chaîne comme u'hi' en Python 2, qui a la même signification en python 3. 'u' a une signification particulière en Python 2, qui indique python 2 pour traiter une chaîne littérale comme type de unicode. « U » en python 3 comme pas de sens, car par défaut (ce qui est appelé le type de prêter à confusion str en python 3 et le type de unicode en python 2) toute chaîne littérale en Python 3 sont Unicode.

Je ne suis pas sûr depuis la version, mais bytes est en fait un str, que vous pouvez voir si vous type(bytes(b"hi")) -.> <type 'str'>

bytearray est un tableau d'octets mutable, un constructeur qui prend une chaîne de caractères.

Je l'ai essayé sur Python 3.0.

En Python 3.0, un iterator bytes retourne ints, pas des chaînes comme Python 2.6 a fait:

for i in bytes(b"hi"):
    print(type(i))

donne:

<class 'int'>
<class 'int'>

iterator bytearray retourne également class 'int's.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top