Question Que fait le caractère 'b' devant une chaîne littérale?


Apparemment, la syntaxe suivante est valide

my_string = b'The string'

J'aimerais savoir:

  1. Qu'est-ce que c'est b caractère devant la chaîne signifie?
  2. Quels sont les effets de l'utilisation?
  3. Quelles sont les situations appropriées pour l'utiliser?

j'ai trouvé un question connexe ici même sur SO, mais cette question concerne PHP, et il indique la b est utilisé pour indiquer que la chaîne est binaire, par opposition à Unicode, qui était nécessaire pour que le code soit compatible avec la version de PHP <6, lors de la migration vers PHP 6. Je ne pense pas que cela s'applique à Python.

J'ai trouvé cette documentation sur le site Python à propos de l'utilisation d'un u caractère dans la même syntaxe pour spécifier une chaîne comme Unicode. Malheureusement, il ne mentionne pas le b caractère n'importe où dans ce document.

Aussi, par curiosité, y a-t-il plus de symboles que le b et u qui fait d'autres choses?


458
2018-06-07 18:14


origine


Réponses:


Citer la documentation Python 2.x:

Un préfixe de «b» ou «B» est ignoré dans   Python 2; cela indique que   littéral devrait devenir un littéral octets   dans Python 3 (par exemple lorsque le code est   automatiquement converti avec 2to3). UNE   Le préfixe «u» ou «b» peut être suivi de   un préfixe 'r'.

le Documentation Python 3.3 États:

Les littéraux d'octets sont toujours préfixés avec 'b' ou 'B'; ils produisent une instance du type bytes au lieu du type str. Ils ne peuvent contenir que des caractères ASCII; Les octets avec une valeur numérique de 128 ou plus doivent être exprimés avec des échappements.


252
2018-06-07 18:16



Python 3.x fait une distinction claire entre les types:

  • str = '...' literals = une séquence de caractères Unicode (UTF-16 ou UTF-32, en fonction de la compilation de Python)
  • bytes = b'...' littéraux = une séquence d'octets (entiers compris entre 0 et 255)

Si vous êtes familier avec Java ou C #, pensez à str comme String et bytes comme byte[]. Si vous êtes familier avec SQL, pensez à str comme NVARCHAR et bytes comme BINARY ou BLOB. Si vous êtes familier avec le registre Windows, pensez à str comme REG_SZ et bytes comme REG_BINARY. Si vous êtes familier avec C (++), alors oubliez tout ce que vous avez appris sur char et des cordes, car Un personnage n'est pas un byte. Cette idée est longtemps obsolète.

Tu utilises str quand vous voulez représenter du texte.

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

Tu utilises bytes lorsque vous souhaitez représenter des données binaires de bas niveau comme des structures.

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

Vous pouvez encoder une str à un bytes objet.

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

Et vous pouvez décoder un bytes dans une str.

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

Mais vous ne pouvez pas mélanger librement les deux types.

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

le b'...' la notation est quelque peu déroutante en ce sens qu'elle permet aux octets 0x01-0x7F d'être spécifiés avec des caractères ASCII au lieu de nombres hexadécimaux.

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

Mais je dois souligner, un personnage n'est pas un octet.

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

En Python 2.x

Les versions antérieures à la version 3.0 de Python manquaient de ce type de distinction entre le texte et les données binaires. Au lieu de cela, il y avait:

  • unicode = u'...' littéraux = séquence de caractères Unicode = 3.x str
  • str = '...'littéraux = séquences d'octets / caractères confondus
    • Habituellement du texte, encodé dans un encodage non spécifié.
    • Mais aussi utilisé pour représenter des données binaires comme struct.pack sortie.

Afin de faciliter la transition 2.x à 3.x, le b'...' La syntaxe littérale a été réinjectée dans Python 2.6, afin de permettre de distinguer les chaînes binaires (ce qui devrait être bytes dans 3.x) à partir de chaînes de texte (qui devrait être str en 3.x). le b préfixe ne fait rien dans 2.x, mais dit à la 2to3 script pour ne pas le convertir en chaîne Unicode en 3.x.

Donc oui, b'...' Les littéraux en Python ont le même objectif que PHP.

Aussi, par curiosité, y a-t-il   plus de symboles que le b et u que faire   autres choses?

le r le préfixe crée une chaîne brute (par exemple, r'\t' est une barre oblique inverse + t au lieu d'un onglet), et des guillemets '''...''' ou """...""" autoriser les littéraux de chaînes multilignes.


409
2018-06-08 02:34



Le b désigne une chaîne d'octets.

Les octets sont les données réelles. Les chaînes sont une abstraction.

Si vous aviez un objet chaîne de plusieurs caractères et que vous preniez un seul caractère, il s'agirait d'une chaîne et sa taille pourrait être supérieure à 1 octet selon l'encodage.

Si prenait 1 octet avec une chaîne d'octets, vous obtiendriez une seule valeur de 8 bits de 0 à 255 et il ne représenterait pas un caractère complet si les caractères dus à l'encodage étaient> 1 octet.

TBH J'utiliserais des chaînes à moins d'avoir une raison spécifique pour utiliser des octets.


12
2018-06-07 18:34



Cela en fait un bytes littéral (ou str 2.x), et est valable pour 2.6+.

le r Le préfixe fait en sorte que les antislashs soient "non interprétés" (pas ignorés, et la différence Est-ce que matière).


8
2018-06-07 18:16



Voici un exemple où l'absence de 'b' lancerait une exception TypeError dans 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'ajout d'un préfixe «b» permettrait de résoudre le problème.


6
2018-06-23 07:02



En plus de ce que d’autres ont dit, notez qu’un seul caractère dans Unicode peut être composé de plusieurs octets.

La façon dont unicode fonctionne est qu'il a pris l'ancien format ASCII (code de 7 bits qui ressemble à 0xxx xxxx) et ajouté séquences multi-octets où tous les octets commencent par 1 (1xxx xxxx) pour représenter les caractères au-delà de l'ASCII afin que Unicode soit rétrocompatible avec 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

1
2018-03-07 12:16