Python Литерал r '\' Не принято - PullRequest
19 голосов
/ 03 апреля 2012

r'\' в Python не работает должным образом. Вместо того, чтобы возвращать строку с одним символом (обратной косой чертой) в ней, она вызывает ошибку SyntaxError. r"\" делает то же самое.

Это довольно громоздко, если у вас есть список путей Windows, подобных этим:

paths = [ r'\bla\foo\bar',
          r'\bla\foo\bloh',
          r'\buff',
          r'\',
          # ...
        ]

Есть ли веская причина, почему этот литерал не принят?

Ответы [ 5 ]

27 голосов
/ 03 апреля 2012

Это соответствует документации :

При наличии префикса 'r' или 'R' символ, следующий за обратной косой чертой, включается в строку безизменить, и все обратные косые черты остаются в строке.Например, строковый литерал r"\n" состоит из двух символов: обратной косой черты и строчной буквы 'n'.Строковые кавычки можно экранировать с помощью обратной косой черты, но обратная косая черта остается в строке;например, r"\"" является допустимым строковым литералом, состоящим из двух символов: обратной косой черты и двойной кавычки;r"\" не является допустимым строковым литералом (даже необработанная строка не может заканчиваться нечетным числом обратных косых черт) .В частности, необработанная строка не может заканчиваться одним обратным слешем (так как обратный слеш будет экранировать следующий символ кавычки).Также обратите внимание, что одиночная обратная косая черта, за которой следует символ новой строки, интерпретируется как эти два символа как часть строки, а не как продолжение строки.

Используйте взамен "\\" или, что еще лучше, используйте / в качестве разделителя пути (да, это работает в Windows).

12 голосов
/ 03 апреля 2012

Обратная косая черта может использоваться, чтобы следующая кавычка не заканчивала строку:

>>> r'\''
"\\'"

То есть r'foo\' или r'\' - это неопределенные литералы.

Обоснование

Поскольку вы специально попросили обосновать это решение по проекту, соответствующие аспекты могут быть следующими (хотя все это, конечно, основано на предположениях):

  • Упрощает лексирование для самого интерпретатора Python (все строковые литералы имеют одинаковую семантику: закрывающая кавычка, за которой не следует нечетное число обратных слешей, завершает строку)
  • Упрощает лексинг для механизмов подсветки синтаксиса (это веский аргумент, потому что большинство языков программирования не имеют необработанных строк, которые все еще заключены в одинарные или двойные кавычки , а многие механизмы подсветки синтаксиса плохо разбиты, потому что они используют неуместные инструменты, такие как регулярные выражения, чтобы выполнять лексинг)

Итак, да , возможно, есть важные причины, по которым был выбран этот способ, даже если вы с ним не согласны, поскольку считаете, что конкретный вариант использования более важен. Однако это не так по следующим причинам:

  • Вы можете просто использовать обычные строковые литералы и избегать обратной косой черты или читать строки из необработанного файла
  • Обратная косая черта в строковых литералах обычно требуется в одном из следующих двух случаев:
    • вы предоставляете строку в качестве ввода для интерпретатора другого языка, который использует обратную косую черту в качестве символа кавычек, например регулярные выражения. В этом случае вам никогда не понадобится обратная косая черта в конце строки
    • вы используете \ в качестве разделителя пути, что обычно не требуется, поскольку Python поддерживает / в качестве разделителя пути в Windows и поскольку os.path.sep.

Решения

Вы можете использовать '\\' или "\\" вместо:

>>> print("\\")
\

Или, если вы абсолютно сумасшедший, вы можете использовать необработанный строковый литерал и комбинировать их с обычными литералами только для конечной обратной косой черты или даже использовать разрезание строк:

>>> r'C:\some\long\freakin\file\path''\\'
'C:\\some\\long\\freakin\\file\\path\\'
>>> r'C:\some\long\freakin\file\path\ '[:-1]
'C:\\some\\long\\freakin\\file\\path\\'

Или, в вашем конкретном случае, вы можете просто сделать:

paths = [ x.replace('/', '\\') for x in '''

  /bla/foo/bar
  /bla/foo/bloh
  /buff
  /

'''.strip().split()]

Что позволит вам сэкономить время при добавлении дополнительных путей в качестве дополнительного бонуса.

2 голосов
/ 03 апреля 2012

Это потому, что в необработанных строках вам нужен способ экранирования одинарных кавычек, когда строка отделяется одинарными кавычками.То же самое с двойными кавычками.

http://docs.python.org/reference/lexical_analysis.html#string-literals

0 голосов
/ 05 апреля 2012

Ответ на мой вопрос («Почему обратный слеш не разрешен в качестве последнего символа в необработанных строках?») На самом деле мне кажется «Это дизайнерское решение», более того, сомнительное.

В некоторых ответах приводятся причины, по которым лексер и некоторые подсветки синтаксиса проще. Я не согласен (и у меня есть опыт написания парсеров и компиляторов, а также разработки IDE). Было бы проще определить необработанные строки с семантикой, что обратный слеш не имеет никакого особого значения. И лексер, и IDE выиграют от этого упрощения.

Текущей ситуацией также является бородавка : в случае, если мне нужна цитата в необработанной строке, я все равно не могу ее использовать. Я могу использовать его, только если мне понадобится обратная косая черта с последующей кавычкой в ​​моей необработанной строке.

Я бы предложил изменить это, но я также вижу проблему взлома существующего кода: - /

0 голосов
/ 03 апреля 2012

Чтобы решить вашу корневую проблему, вы можете использовать / в путях на Windows в Python просто отлично .

r'' и r""синтаксис (raw) в первую очередь предназначен для работы с регулярными выражениями.В действительности вы ничего не получите в случае работы с путями, как вы ожидаете, особенно когда строка заканчивается \.

В противном случае, если вы настаиваете на использовании \, либо используйте '\\' или "\\", вы должны экранировать escape-символ \;это не красиво, использование / или os.path.sep является лучшим решением.

...