Что именно делают строковые флаги “u" и “r”, и что такое необработанные строковые литералы?
-
21-09-2019 - |
Вопрос
Спрашивая при этом этот вопрос, Я понял, что мало что знаю о необработанных струнах.Для кого-то, кто называет себя тренером Django, это отстой.
Я знаю, что такое кодировка, и я знаю, что u''
alone делает это, так как я получаю то, что называется Unicode.
Но что делает
r''
сделать именно так?В какую строку это приводит?И, прежде всего, что, черт возьми, делает
ur''
делать?Наконец, есть ли какой-нибудь надежный способ вернуться от строки в Юникоде к простой необработанной строке?
Да, и, кстати, если в вашей системе и вашем текстовом редакторе установлена кодировка UTF-8, то
u''
на самом деле что-нибудь делаешь?
Решение
На самом деле нет никакого «сырого» нить";есть сырые строковые литералы, которые в точности представляют собой строковые литералы, отмеченные знаком 'r'
перед вступительной цитатой.
«Необработанный строковый литерал» — это немного другой синтаксис строкового литерала, в котором обратная косая черта, \
, воспринимается как означающая «просто обратную косую черту» (за исключением случаев, когда она идет прямо перед кавычкой, которая в противном случае завершила бы литерал) — никаких «escape-последовательностей» для обозначения новой строки, табуляции, пробелов, перевода страницы и т. д.В обычных строковых литералах каждую обратную косую черту необходимо удваивать, чтобы она не воспринималась как начало escape-последовательности.
Этот вариант синтаксиса существует главным образом потому, что синтаксис шаблонов регулярных выражений насыщен обратными косыми чертами (но никогда в конце, поэтому приведенное выше предложение «исключение» не имеет значения), и он выглядит немного лучше, если вы не удваиваете каждый из них: - вот и все.Он также приобрел некоторую популярность для выражения собственных путей к файлам Windows (с обратными косыми чертами вместо обычных косых черт, как на других платформах), но это требуется очень редко (поскольку обычные косые черты в основном хорошо работают и в Windows) и несовершенно (из-за пункта «исключение»). выше).
r'...'
— это байтовая строка (в Python 2.*), ur'...'
— это строка в Юникоде (опять же, в Python 2.*), и любой из трех других типов кавычек также создает точно такие же типы строк (например, r'...'
, r'''...'''
, r"..."
, r"""..."""
все это байтовые строки и т. д.).
Не уверен, что вы имеете в виду под «идти назад" - нет внутренних направлений вперед и назад, потому что нет необработанной строки тип, это просто альтернативный синтаксис для выражения совершенно обычных строковых объектов, байтов или юникода, какими бы они ни были.
И да, в Python 2.*, u'...'
является конечно, всегда отличается от просто '...'
-- первое — это строка в Юникоде, второе — байтовая строка.В какой кодировке может быть выражен литерал — это совершенно ортогональный вопрос.
Например, рассмотрим (Python 2.6):
>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34
Объект Unicode, конечно, занимает больше места в памяти (очевидно, очень небольшая разница для очень короткой строки ;-).
Другие советы
В python существует два типа строк:традиционный str
тип и новее unicode
Тип.Если вы вводите строковый литерал без u
впереди вы получаете старое str
тип, в котором хранятся 8-битные символы, и с u
спереди вы получаете более новый unicode
тип, который может хранить любой символ Юникода.
Тот самый r
вообще не меняет тип, он просто изменяет способ интерпретации строкового литерала.Без r
, обратная косая черта обрабатывается как экранирующие символы.С помощью r
, обратная косая черта обрабатывается как буквальная.В любом случае, тип один и тот же.
ur
это, конечно, строка Unicode, где обратные косые черты являются буквальными обратными косыми чертами, а не частью escape-кодов.
Вы можете попытаться преобразовать строку в Юникоде в старую строку, используя str()
функция, но если есть какие-либо символы юникода, которые не могут быть представлены в старой строке, вы получите исключение.При желании вы могли бы сначала заменить их вопросительными знаками, но, конечно, это привело бы к тому, что эти символы стали бы нечитаемыми.Не рекомендуется использовать str
введите, если вы хотите корректно обрабатывать символы Юникода.
'сырая строка' означает, что он сохраняется в том виде, в котором он появляется.Например, '\'
это просто обратная косая черта вместо побег.
Префикс «u» означает, что значение имеет тип unicode
скорее, чем str
.
Необработанные строковые литералы с префиксом «r» экранируют любые escape-последовательности внутри них, поэтому len(r"\n")
это 2.Поскольку они экранируют escape-последовательности, вы не можете закончить строковый литерал одной обратной косой чертой:это недопустимая escape-последовательность (например. r"\"
).
«Raw» не является частью типа, это всего лишь один из способов представления значения.Например, "\\n"
и r"\n"
являются идентичными значениями, как и 32
, 0x20
, и 0b100000
идентичны.
Вы можете иметь необработанные строковые литералы Юникода:
>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2
Кодировка исходного файла просто определяет, как интерпретировать исходный файл, иным образом не влияет на выражения или типы.Однако это рекомендуемые чтобы избежать кода, в котором кодировка, отличная от ASCII, изменит значение:
Файлы, использующие ASCII (или UTF-8 для Python 3.0), не должны иметь файлов cookie для кодирования.Latin-1 (или UTF-8) следует использовать только в том случае, если в комментарии или строке документации необходимо упомянуть имя автора, требующее Latin-1;в противном случае использование экранирующих символов \x, \u или \U является предпочтительным способом включения данных, отличных от ASCII, в строковые литералы.
Позвольте мне объяснить это просто:В Python 2 вы можете хранить строку в двух разных типах.
Первый из них ASCII который ул. введите python, он использует 1 байт памяти.(256 символов, в основном будут храниться английские алфавиты и простые символы)
2-й тип – это ЮНИКОД который Юникод введите python, он использует 2 байта памяти.(65536 символов, включая все символы всех языков мира)
По умолчанию Python предпочитает ул. введите, но если вы хотите сохранить строку в Юникод типа ты можешь поставить ты перед текстом типа ты'текст' или вы можете сделать это, позвонив Юникод('текст')
Так ты это всего лишь короткий способ вызвать функцию для приведения ул. к Юникод.Вот и все!
Сейчас р часть, вы помещаете ее перед текстом, чтобы сообщить компьютеру, что текст представляет собой необработанный текст, обратная косая черта не должна быть экранирующим символом. р'\н' не создаст новый символ строки.Это просто текст, содержащий 2 символа.
Если вы хотите конвертировать ул. к Юникод а также поместите туда необработанный текст, используйте ты потому что RU выдаст ошибку.
ТЕПЕРЬ, важная часть:
Вы не можете сохранить одну обратную косую черту, используя р, это единственное исключение.Итак, этот код выдаст ошибку: р'\'
Чтобы сохранить обратную косую черту (только одну), вам нужно использовать '\\'
Если вы хотите сохранить более 1 символа, вы все равно можете использовать р нравиться р'\\' как вы и ожидали, создаст 2 обратные косые черты.
Я не знаю, почему р не работает с одним хранилищем с обратной косой чертой, но причина пока никем не описана.Я надеюсь, что это ошибка.
Может быть, это очевидно, а может и нет, но вы можете сделать строку '\' позвонив х=хр(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
Строковые литералы Юникода
Строковые литералы Юникода (строковые литералы с префиксом u
) являются больше не используется в Python 3.Они все еще действительны, но просто в целях совместимости с Питоном 2.
Необработанные строковые литералы
Если вы хотите создать строковый литерал, состоящий только из легко набираемых символов, таких как английские буквы или цифры, вы можете просто ввести их: 'hello world'
.Но если вы хотите включить еще несколько экзотических персонажей, вам придется использовать обходной путь.Одним из обходных путей является Escape-последовательности.Таким образом, вы можете, например, представить новую строку в строке, просто добавив два легко вводимых символа. \n
к вашему строковому литералу.Поэтому, когда вы печатаете 'hello\nworld'
строка, слова будут напечатаны в отдельных строках.Это очень удобно!
С другой стороны, в некоторых ситуациях вы хотите создать строковый литерал, содержащий escape-последовательности, но не хотите, чтобы они интерпретировались Python.Вы хотите, чтобы они были сырой.Посмотрите на эти примеры:
'New updates are ready in c:\windows\updates\new'
'In this lesson we will learn what the \n escape sequence does.'
В таких ситуациях вы можете просто поставить перед строковым литералом префикс r
персонаж такой: r'hello\nworld'
и никакие escape-последовательности не будут интерпретироваться Python.Строка будет напечатана точно так, как вы ее создали.
Необработанные строковые литералы не являются полностью «сырыми»?
Многие люди ожидают, что необработанные строковые литералы будут необработанными в том смысле, что «Все, что помещено между кавычками, игнорируется Python».Это неправда.Python по-прежнему распознает все escape-последовательности, он просто не интерпретирует их — вместо этого он оставляет их без изменений.Это означает, что необработанные строковые литералы по-прежнему должны быть допустимыми строковыми литералами.
Из лексическое определение строкового литерала:
string ::= "'" stringitem* "'"
stringitem ::= stringchar | escapeseq
stringchar ::= <any source character except "\" or newline or the quote>
escapeseq ::= "\" <any source character>
Понятно, что строковые литералы (необработанные или нет), содержащие символ голой кавычки: 'hello'world'
или заканчивая обратной косой чертой: 'hello world\'
недействительны.