¿Qué hacen exactamente las banderas de cadena" u "y" r", y qué son los literales de cadena sin procesar?


Mientras hacía esta pregunta, me di cuenta de que no sabía mucho sobre cadenas sin procesar. Para alguien que dice ser entrenador de Django, esto apesta.

Sé lo que es una codificación, y sé lo que hace u'' por sí solo, ya que obtengo lo que es Unicode.

  • Pero, ¿qué hace r'' exactamente? ¿En qué tipo de cadena resulta?

  • Y sobre todo, ¿qué diablos hace ur''?

  • Finalmente, ¿hay alguna forma confiable de regresar de un Unicode string a una simple cadena raw?

  • Ah, y por cierto, si su sistema y su conjunto de caracteres de editor de texto están configurados en UTF-8, ¿u'' realmente hace algo?

Author: wim, 2010-01-17

6 answers

No hay realmente ningún "raw string"; hay raw literales de cadena, que son exactamente los literales de cadena marcados por un 'r' antes de la cita inicial.

Un "literal de cadena raw" es una sintaxis ligeramente diferente para un literal de cadena, en la que una barra invertida, \, se toma como "solo una barra invertida" (excepto cuando viene justo antes de una cita que de otra manera terminaría el literal) no no hay "secuencias de escape" para representar nuevas líneas, pestañas, espacios atrás, form-feeds, y así sucesivamente. En literales de cadena normales, cada barra invertida debe duplicarse para evitar ser tomada como el inicio de una secuencia de escape.

Esta variante de sintaxis existe principalmente porque la sintaxis de los patrones de expresión regular es pesada con barras invertidas (pero nunca al final, por lo que la cláusula "excepto" anterior no importa) y se ve un poco mejor cuando se evita duplicar cada una de ellas that eso es todo. También ganó cierta popularidad para expresar rutas de archivo nativas de Windows (con barras invertidas en lugar de barras regulares como en otras plataformas), pero eso es muy rara vez necesario (ya que las barras normales en su mayoría funcionan bien en Windows también) e imperfecto (debido a la cláusula "excepto" anterior).

r'...' es una cadena de bytes (en Python 2.* ), ur'...' es una cadena Unicode (de nuevo, en Python 2.* ), y cualquiera de los otros tres tipos de comillas también produce exactamente los mismos tipos de cadenas (por ejemplo r'...', r'''...''', r"...", r"""...""" son todas cadenas de bytes, y así sucesivamente).

No estoy seguro de qué quieres decir con " ir hacia atrás" - no hay direcciones intrínsecamente hacia atrás y hacia adelante, porque no hay cadena cruda tipo, es solo una sintaxis alternativa para expresar objetos de cadena perfectamente normales, byte o unicode como pueden ser.

Y sí, en Python 2.*, u'...' es por supuesto siempre distinto de solo '...' the el primero es una cadena unicode, el segundo es una cadena de bytes. Lo que codifica el literal podría ser expresado en es un completamente ortogonal cuestión.

Por ejemplo, considere (Python 2.6):

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

El objeto Unicode por supuesto ocupa más espacio de memoria (diferencia muy pequeña para una cadena muy corta, obviamente ;-).

 511
Author: Alex Martelli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-04-29 20:22:55

Hay dos tipos de cadena en python: el tipo tradicional str y el tipo más nuevo unicode. Si escribe un literal de cadena sin el u en frente, obtiene el antiguo tipo str que almacena caracteres de 8 bits, y con el u en frente, obtiene el nuevo tipo unicode que puede almacenar cualquier carácter Unicode.

El r no cambia el tipo en absoluto, solo cambia cómo se interpreta el literal de la cadena. Sin r, las barras invertidas se tratan como caracteres de escape. Con el r, las barras invertidas se tratan como literales. De cualquier manera, el tipo es el mismo.

ur es, por supuesto, una cadena Unicode donde las barras invertidas son barras invertidas literales, no parte de códigos de escape.

Puede intentar convertir una cadena Unicode a una cadena antigua utilizando la función str(), pero si hay caracteres unicode que no se pueden representar en la cadena antigua, obtendrá una excepción. Podría reemplazarlos con signos de interrogación primero si lo desea, pero por supuesto esto causaría esos caracteres son ilegibles. No se recomienda utilizar el tipo str si desea manejar correctamente los caracteres unicode.

 142
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-28 18:51:54

'cadena sin procesar' significa que se almacena tal como aparece. por ejemplo, ' \ ' es solo una barra invertida en lugar de un escape.

 33
Author: xiaolong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-06 01:21:38

Un prefijo "u" denota el valor tiene tipo unicode en lugar de str.

Los literales de cadena sin procesar, con un prefijo "r", escapan cualquier secuencia de escape dentro de ellos, por lo que len(r"\n") es 2. Debido a que escapan secuencias de escape, no puede terminar un literal de cadena con una sola barra invertida: esa no es una secuencia de escape válida (por ejemplo, r"\").

"Raw" no es parte del tipo, es simplemente una forma de representar el valor. Por ejemplo, "\\n" y r"\n" son valores idénticos, al igual que 32, 0x20, y 0b100000 son idénticos.

Puedes tener literales de cadena raw unicode:

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

La codificación del archivo de origen solo determina cómo interpretar el archivo de origen, no afecta a expresiones o tipos de otro modo. Sin embargo, se recomienda evitar el código donde una codificación distinta a ASCII cambiaría el significado:

Los archivos que usan ASCII (o UTF-8, para Python 3.0) no deben tener una cookie de codificación. Latin-1 (o UTF-8) solo debe usarse cuando un comentario o docstring necesita mencionar un nombre de autor que requiere Latin-1; de lo contrario, usar \x, \u o \U escapes es la forma preferida de incluir datos no ASCII en literales de cadena.

 28
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-17 16:55:23

Déjame explicarlo simplemente: En python 2, puede almacenar cadenas en 2 tipos diferentes.

La primera es ASCII que es str tipo en python, utiliza 1 byte de memoria. (256 caracteres, almacenará principalmente alfabetos en inglés y símbolos simples)

El 2do tipo es UNICODE que es unicode tipo en python, utiliza 2 bytes de memoria. (65536 caracteres, por lo que esto incluye todos los caracteres de todos los idiomas en la tierra)

De forma predeterminada, python prefieren str tipo, pero si desea almacenar una cadena en unicode tipo puede poner u delante del texto como u'text' o usted puede hacer esto llamando a unicode('texto')

Así que ues solo una forma corta de llamar a una función para convertir stra unicode. ¡Eso es!

Ahora la parte r, la pones delante del texto para decirle a la computadora que el texto es texto sin procesar, la barra invertida no debe ser un carácter de escape. r'\n' no creará un nuevo carácter de línea. Es solo texto plano que contiene 2 caracteres.

Si desea convertir str a unicode y también poner texto sin procesar allí, use ur porque ru generará un error.

AHORA, la parte importante:

No puede almacenar una barra invertida usando r, es la única excepción. Así que este código producirá error: r'\'

Para almacenar una barra invertida (solo una) es necesario uso '\\'

Si desea almacenar más de 1 caracteres, todavía puede usar r como r'\\' producirá 2 barras invertidas como esperaba.

No se la razón por la que r no funciona con un almacenamiento de barra invertida, pero la razón aún no ha sido descrita por nadie. Espero que sea un error.

 16
Author: off99555,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-10 16:23:38

Tal vez esto sea obvio, tal vez no, pero puede hacer que la cadena '\' llamando a 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
Author: Bomba Ps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-15 07:37:24