web-dev-qa-db-fra.com

Pourquoi les barres obliques inverses apparaissent-elles deux fois?

Lorsque je crée une chaîne contenant des barres obliques inverses, elles sont dupliquées:

>>> my_string = "why\does\it\happen?"
>>> my_string
'why\\does\\it\\happen?'

Pourquoi?

44
Zero Piraeus

Ce que vous voyez est la représentation de my_string Créée par sa méthode __repr__() . Si vous l'imprimez, vous pouvez voir que vous avez réellement des barres obliques inverses, comme vous le vouliez:

>>> print(my_string)
why\does\it\happen?

La chaîne ci-dessous contient trois caractères, pas quatre:

>>> 'a\\b'
'a\\b'
>>> len('a\\b')
3

Vous pouvez obtenir la représentation standard d'une chaîne (ou de tout autre objet) avec la fonction intégrée repr() :

>>> print(repr(my_string))
'why\\does\\it\\happen?'

Python représente les barres obliques inverses dans les chaînes sous la forme \\ Car la barre oblique inverse est un caractère d'échappement - par exemple, \n Représente une nouvelle ligne et \t Représente un onglet.

Cela peut parfois vous causer des ennuis:

>>> print("this\text\is\not\what\it\seems")
this    ext\is
ot\what\it\seems

Pour cette raison, il doit y avoir un moyen de dire Python vous vraiment voulez les deux caractères \n plutôt qu'une nouvelle ligne, et vous le faites en échappant à la barre oblique inverse elle-même, avec une autre:

>>> print("this\\text\is\what\you\\need")
this\text\is\what\you\need

Lorsque Python renvoie la représentation d'une chaîne, il joue en toute sécurité, échappant à toutes les barres obliques inverses (même si elles ne feraient pas autrement partie d'une séquence d'échappement), et c'est ce que vous voyez. Cependant , la chaîne elle-même ne contient que des barres obliques inverses simples.

Pour plus d'informations sur les littéraux de chaîne de Python, consultez: Littéraux de chaîne et octets dans la documentation Python.

62
Zero Piraeus

Comme réponse de Zero Piraeus l'explique, utiliser des barres obliques inverses comme celle-ci (en dehors de littéraux de chaîne bruts ) est une mauvaise idée.

Mais il y a un problème supplémentaire: à l'avenir, ce sera une erreur d'utiliser une séquence d'échappement non définie comme \d, au lieu de signifier une barre oblique inverse littérale suivie d'un d. Donc, au lieu de simplement avoir de la chance que votre chaîne utilise le \d au lieu de \t donc il a fait ce que vous vouliez probablement, il ne fera certainement pas ce que vous voulez.

Depuis 3.6, il lève déjà un DeprecationWarning, bien que la plupart des gens ne les voient pas. Il deviendra un SyntaxError dans une future version.


Dans de nombreux autres langages, y compris C, l'utilisation d'une barre oblique inverse qui ne démarre pas une séquence d'échappement signifie que la barre oblique inverse est ignorée.

Dans quelques langues, dont Python, une barre oblique inverse qui ne démarre pas une séquence d'échappement est une barre oblique inverse littérale.

Dans certains langages, pour éviter toute confusion quant à savoir si le langage est de type C ou de type Python, et pour éviter le problème avec \Foo fonctionne mais \foo ne fonctionne pas, une barre oblique inverse qui ne démarre pas une séquence d'échappement est illégale.

7
abarnert