Question Que font exactement les drapeaux de chaîne "u" et "r" et que sont les littéraux de chaîne bruts?


Tout en demandant cette question, J'ai réalisé que je ne savais pas grand-chose sur les cordes brutes. Pour quelqu'un qui prétend être un entraîneur de Django, c'est nul.

Je sais ce qu'est un encodage, et je sais ce que u seul fait depuis que je reçois ce qui est Unicode.

Mais qu'est-ce que r faire exactement? Quel genre de chaîne résulte-t-il?

Et surtout, que diable fait ur faire?

Enfin, existe-t-il un moyen fiable de revenir d'une chaîne Unicode à une simple chaîne brute?

Ah, et au fait, si votre système et votre jeu de caractères d'éditeur de texte sont définis sur UTF-8, est-ce que u fait quoi que ce soit?


431
2018-01-17 16:22


origine


Réponses:


Il n'y a pas vraiment de "brut chaîne"; il y a cru littéraux de chaîne, qui sont exactement les littéraux de chaîne marqués par un 'r' avant la citation d'ouverture.

Un "littéral de chaîne brut" est une syntaxe légèrement différente pour un littéral de chaîne, dans lequel une barre oblique inverse, \, est pris comme signifiant "juste un backslash" (sauf quand il se trouve juste avant une citation qui mettrait fin au littéral) - pas de "séquences d'échappement" pour représenter les retours à la ligne, les tabulations, les backspaces, etc. Dans les littéraux de chaîne normaux, chaque barre oblique inverse doit être doublée pour éviter d'être considérée comme le début d'une séquence d'échappement.

Cette variante de syntaxe existe principalement parce que la syntaxe des patterns d'expression régulière est lourde avec des backslashes (mais jamais à la fin, donc la clause "except" ci-dessus n'a pas d'importance) et elle semble un peu meilleure quand vous évitez de doubler - c'est tout. Il a également gagné en popularité pour exprimer les chemins de fichiers Windows natifs (avec des barres obliques inversées à la place des barres obliques comme sur les autres plates-formes), mais cela est rarement nécessaire (puisque les barres normales fonctionnent généralement bien sous Windows). au dessus).

r'...' est une chaîne d'octets (en Python 2. *), ur'...' est une chaîne Unicode (encore une fois, en Python 2. *), et l'un des trois autres types de citations produit également exactement les mêmes types de chaînes (par exemple r'...', r'''...''', r"...", r"""...""" sont toutes les chaînes d'octets, et ainsi de suite).

Je ne sais pas ce que tu veux dire par "aller arrière"- il n'y a pas de directions intrinsèquement en arrière et en avant, car il n'y a pas de chaîne brute type, ce n'est qu'une syntaxe alternative pour exprimer des objets de chaîne, octet ou unicode parfaitement normaux.

Et oui, en Python 2. *, u'...'  est bien sûr toujours distinct de juste '...' - le premier est une chaîne unicode, le dernier est une chaîne d'octets. L'encodage du littéral est une question complètement orthogonale.

Par exemple, considérons (Python 2.6):

>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34

L'objet Unicode prend bien sûr plus d'espace mémoire (très petite différence pour une chaîne très courte, évidemment ;-).


476
2018-01-17 16:38



Il existe deux types de chaînes en python: le traditionnel str tapez et le plus récent unicode type. Si vous tapez un littéral de chaîne sans le udevant vous obtenez le vieux str type qui stocke les caractères 8 bits, et avec le u devant vous obtenez le plus récent unicode type qui peut stocker n'importe quel caractère Unicode.

le r ne change pas du tout le type, cela change simplement la façon dont le littéral de chaîne est interprété. Sans le rLes barres obliques inverses sont traitées comme des caractères d'échappement. Avec le r, les antislashs sont traités comme littéraux. De toute façon, le type est le même.

ur est bien sûr une chaîne Unicode où les barres obliques inverses sont des barres obliques inverses littérales, ne faisant pas partie des codes d'échappement.

Vous pouvez essayer de convertir une chaîne Unicode en une ancienne chaîne en utilisant str() fonction, mais s'il existe des caractères Unicode qui ne peuvent pas être représentés dans l'ancienne chaîne, vous obtiendrez une exception. Vous pouvez les remplacer par des points d'interrogation si vous le souhaitez, mais bien sûr, cela rendrait ces caractères illisibles. Il n'est pas recommandé d'utiliser le str tapez si vous voulez gérer correctement les caractères Unicode.


131
2018-01-17 16:26



«chaîne brute» signifie qu'elle est stockée telle qu'elle apparaît. par exemple, '\' est juste un backslash au lieu d'un échappement.


32
2018-03-06 01:21



Un préfixe "u" indique la valeur a le type unicode plutôt que str.

Les littéraux de chaîne bruts, avec un préfixe "r", échappent à toutes les séquences d’échappement len(r"\n") is 2. Puisqu'ils échappent aux séquences d'échappement, vous ne pouvez pas terminer un littéral de chaîne avec une seule barre oblique inverse: ce n'est pas une séquence d'échappement valide (par ex. r"\").

"Raw" ne fait pas partie du type, c'est simplement une façon de représenter la valeur. Par exemple, "\\n" et r"\n" sont des valeurs identiques, tout comme 32, 0x20, et 0b100000 sont identiques.

Vous pouvez avoir des littéraux de chaîne bruts unicode:

>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2

L'encodage du fichier source détermine uniquement comment interpréter le fichier source, il n'affecte pas les expressions ou les types dans le cas contraire. Cependant, c'est conseillé pour éviter le code où un codage autre que ASCII changerait la signification:

Les fichiers utilisant ASCII (ou UTF-8, pour Python 3.0) ne doivent pas avoir de cookie de codage. Latin-1 (ou UTF-8) ne doit être utilisé que lorsqu'un commentaire ou une docstring doit mentionner un nom d'auteur nécessitant Latin-1; sinon, l'utilisation de \ x, \ u ou \ U échappements est la méthode préférée pour inclure des données non-ASCII dans les littéraux de chaîne.


25
2018-01-17 16:25



Laissez-moi l'expliquer simplement: En python 2, vous pouvez stocker une chaîne dans deux types différents.

Le premier est ASCII lequel est str tapez en python, il utilise 1 octet de mémoire. (256 caractères, stocke la plupart des alphabets anglais et des symboles simples)

Le 2ème type est UNICODE lequel est unicode tapez en python, il utilise 2 octets de mémoire. (65536 caractères, donc cela inclut tous les caractères de toutes les langues sur terre)

Par défaut, python préférera str tapez mais si vous voulez stocker la chaîne dans unicode tapez vous pouvez mettre tu devant le texte comme u'text ' ou vous pouvez le faire en appelant unicode ('text')

Alors tu est juste un court chemin pour appeler une fonction à lancer strà unicode. C'est tout!

Maintenant le r part, vous le mettez devant le texte pour dire à l'ordinateur que le texte est du texte brut, la barre oblique inverse ne doit pas être un caractère échappé. r '\ n' ne créera pas un nouveau caractère de ligne. C'est juste du texte simple contenant 2 caractères.

Si vous voulez convertir strà unicode et aussi mettre du texte brut là-dedans, utilisez ur car ru va générer une erreur.

MAINTENANT, la partie importante:

Vous ne pouvez pas stocker une barre oblique inverse en utilisant rc'est la seule exception. Donc, ce code produira une erreur: r '\'

Pour stocker une barre oblique inverse (une seule), vous devez utiliser '\\'

Si vous souhaitez stocker plus de 1 caractères, vous pouvez toujours utiliser r comme r '\\' produira 2 antislashs comme prévu.

Je ne sais pas pourquoi r ne fonctionne pas avec un backslash de stockage, mais la raison n'est pas encore décrite par quiconque. J'espère que c'est un bug.


12
2017-08-25 21:01



Peut-être que c'est évident, peut-être pas, mais vous pouvez faire la chaîne '\' en appelant x = chr (92)

x=chr(92)
print type(x), len(x) # <type 'str'> 1
y='\\'
print type(y), len(y) # <type 'str'> 1
x==y   # True
x is y # False

2
2018-05-15 07:37