Что именно делают "u" и "r" строковые флаги, и каковы исходные строковые литералы?
Когда я задавал этот вопрос, я понял, что не знаю много о сырых струнах. Для кого-то, претендующего на роль тренера в Django, это отстой.
Я знаю, что такое кодирование, и я знаю, что u''
в одиночку делает, так как я получаю то, что Unicode.
-
Но что делает r''
точно"? В какой строке это результат?
-
И, прежде всего, что делает " ur''
?
-
Наконец, есть ли какой-либо надежный способ вернуться из строки Unicode к простой исходной строке?
-
Ах, и, кстати, если ваша система и текстовый редактор кодировка устанавливается в кодировке UTF-8, это u''
на самом деле сделать что - нибудь?
Ответы
Ответ 1
На самом деле не существует "сырой строки"; есть исходные строковые литералы, которые в точности соответствуют строковым литералам, отмеченным 'r'
перед началом цитаты.
"Необработанный строковый литерал" представляет собой несколько иной синтаксис для строкового литерала, в котором используется обратная косая черта \
, как означающая "просто обратная косая черта" (за исключением случаев, когда она поступает прямо перед цитатой, которая в противном случае завершается буква) - нет "escape-последовательностей" для представления новых строк, вкладок, обратных пространств, форм-каналов и т.д. В обычных строковых литералах каждая обратная косая черта должна быть удвоена, чтобы не быть принятой за начало escape-последовательности.
Этот вариант синтаксиса существует главным образом потому, что синтаксис шаблонов регулярных выражений тяжел с обратными косыми чертами (но никогда в конце, поэтому вышеописанное предложение "исключение" не имеет значения), и оно выглядит немного лучше, когда вы избегаете удвоения каждого из них - все. Также стало популярным распространять собственные пути файлов Windows (с обратными косыми чертами вместо обычных косых черт, например, на других платформах), но это очень редко необходимо (поскольку нормальные косые черты в основном работают отлично на Windows) и несовершенны (из-за предложения "except" выше).
r'...'
является байтовой строкой (в Python 2. *), ur'...'
является строкой Unicode (опять же, в Python 2. *), и любой из трех других видов цитирования также производит точно такие же типы (например, r'...'
, r'''...'''
, r"..."
, r"""..."""
- все байтовые строки и т.д.).
Не уверен, что вы подразумеваете под "возвратом" - нет внутренних и обратных направлений, потому что нет исходной строки type, это просто альтернативный синтаксис, чтобы выражать абсолютно нормальные строковые объекты, байт или unicode, как они могут быть.
И да, в Python 2. *, u'...'
есть, конечно, всегда отличная от просто '...'
- первая строка юникода, последняя - байтовая строка. Какая кодировка литерала может быть выражена, является полностью ортогональной проблемой.
Например, рассмотрим (Python 2.6):
>>> sys.getsizeof('ciao')
28
>>> sys.getsizeof(u'ciao')
34
Конечно, объект Unicode занимает больше места в памяти (очень маленькая разница для очень короткой строки, очевидно, -).
Ответ 2
В python существует два типа строк: традиционный тип str
и новый тип unicode
. Если вы вводите строковый литерал без u
впереди, вы получаете старый тип str
, в котором хранятся 8-битные символы, а с u
впереди вы получаете новый тип unicode
, который может хранить любой символ Unicode.
r
не изменяет тип вообще, он просто изменяет интерпретацию строкового литерала. Без r
обратные косые черты рассматриваются как escape-символы. С r
обратная косая черта рассматривается как буквальная. В любом случае, тип тот же.
ur
, конечно, является строкой Unicode, где обратные косые черты являются буквальными обратными косыми чертами, а не частью escape-кодов.
Вы можете попытаться преобразовать строку Unicode в старую строку с помощью функции str()
, но если есть какие-либо символы Unicode, которые не могут быть представлены в старой строке, вы получите исключение. Сначала вы можете заменить их вопросительными знаками, но, конечно, это может привести к тому, что эти символы не будут читаемы. Не рекомендуется использовать тип str
, если вы хотите правильно обрабатывать символы юникода.
Ответ 3
"Необработанная строка" означает, что она сохраняется, как кажется. Например, '\'
- это просто обратный слеш вместо экранирования.
Ответ 4
Префикс "u" означает, что значение имеет тип unicode
, а не str
.
Исходные строковые литералы с префиксом "r" избегают любых escape-последовательностей внутри них, поэтому len(r"\n")
равно 2. Поскольку они избегают escape-последовательностей, вы не можете закончить строковый литерал одним обратным слэшем: это не допустимый escape-код (например, r"\"
).
"Сырье" не является частью типа, это всего лишь один способ представления значения. Например, "\\n"
и r"\n"
являются одинаковыми значениями, так же как 32
, 0x20
и 0b100000
идентичны.
У вас могут быть строковые литералы в формате unicode:
>>> u = ur"\n"
>>> print type(u), len(u)
<type 'unicode'> 2
Кодировка исходного файла определяет, как интерпретировать исходный файл, иначе он не влияет на выражения или типы. Тем не менее, рекомендуется, чтобы избежать кода, в котором кодировка, отличная от ASCII, изменит значение:
Файлы, использующие ASCII (или UTF-8 для Python 3.0), не должны содержать файл cookie для кодирования. Latin-1 (или UTF-8) следует использовать только в том случае, если комментарий или docstring должны указывать имя автора, для которого требуется Latin-1; в противном случае использование \x,\u или\U escapes является предпочтительным способом включения данных, отличных от ASCII, в строковых литералах.
Ответ 5
Позвольте мне объяснить это просто:
В python 2 вы можете хранить строку в двух разных типах.
Первый - ASCII, который имеет тип str в python, он использует 1 байт памяти. (256 символов, будут хранить в основном английские алфавиты и простые символы)
Второй тип UNICODE, который является unicode в python, он использует 2 байта памяти. (65536 символов, поэтому сюда относятся все символы всех языков на Земле)
По умолчанию python предпочитает тип str, но если вы хотите сохранить строку в типе unicode, вы можете поставить u перед текст как u'text ', или вы можете сделать это, вызвав unicode (' text ')
Так что u - это всего лишь короткий способ вызвать функцию для перевода str в unicode. Что это!
Теперь часть r, вы помещаете ее перед текстом, чтобы сообщить компьютеру, что текст является сырым текстом, обратная косая черта не должна быть экранирующим символом. r '\n' не создаст новый символ строки. Это просто текст, содержащий 2 символа.
Если вы хотите преобразовать str в unicode, а также добавить туда текст, используйте ur, потому что ru > приведет к ошибке.
СЕЙЧАС, важная часть:
Вы не можете сохранить одну обратную косую черту с помощью r, это единственное исключение.
Таким образом, этот код приведет к ошибке: r '\'
Чтобы сохранить обратную косую черту (только одну), вам нужно использовать '\\'
Если вы хотите сохранить более 1 символа, вы все равно можете использовать r, например r '\\' будет производить 2 обратных слэша, как вы ожидали.
Я не знаю причину, по которой r не работает с одним хранилищем обратного слэша, но причина еще не описана кем-либо. Я надеюсь, что это ошибка.
Ответ 6
Возможно, это очевидно, может быть, нет, но вы можете сделать строку '\', вызвав 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
Ответ 7
Строковые литералы Юникода
Строковые литералы Unicode (строковые литералы с префиксом u
) больше не используются в Python 3. Они по-прежнему допустимы, но только для целей совместимости с Python 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'hello\nworld'
префикс строкового литерала символом 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\'
, недопустимы.