str - python unicode to utf8
¿Qué hacen exactamente las marcas de cadena “u” y “r”, y qué son los literales de cadena en bruto? (6)
Al hacer esta pregunta , me di cuenta de que no sabía mucho acerca de las cadenas en bruto. Para alguien que dice ser un entrenador de Django, esto apesta.
Sé lo que es una codificación, y sé lo que hace u''''
solo porque tengo lo que es Unicode.
Pero, ¿qué hace
r''''
exactamente? ¿En qué tipo de cuerda resulta?Y, sobre todo, ¿qué diablos hace tu?
Finalmente, ¿hay alguna forma confiable de volver de una cadena Unicode a una cadena simple?
Ah, y por cierto, si su sistema y el conjunto de caracteres de su editor de texto están configurados en UTF-8, ¿realmente hace algo?
''cadena cruda'' significa que se almacena como aparece. por ejemplo, ''/' es solo una barra invertida en lugar de un escape.
Hay dos tipos de cadenas en python: el tipo str
tradicional y el tipo unicode
más nuevo. Si escribe una cadena literal sin la u
en frente, obtendrá el tipo de str
antiguo que almacena caracteres de 8 bits, y con la u
en frente obtendrá el tipo de unicode
más nuevo que puede almacenar cualquier carácter de Unicode.
La r
no cambia el tipo en absoluto, solo cambia la forma en que se interpreta la cadena literal. Sin la r
, las barras invertidas se tratan como caracteres de escape. Con la r
, las barras invertidas se tratan como literales. De cualquier manera, el tipo es el mismo.
Por supuesto, ur
es una cadena Unicode donde las barras invertidas son barras invertidas literales, que no forman parte de los códigos de escape.
Puede intentar convertir una cadena Unicode en una cadena antigua usando la función str()
, pero si hay algún carácter Unicode que no pueda representarse en la cadena antigua, obtendrá una excepción. Si lo desea, puede reemplazarlas con signos de interrogación, pero, por supuesto, esto hará que esos caracteres sean ilegibles. No se recomienda usar el tipo str
si desea manejar correctamente los caracteres Unicode.
Permítame explicarlo simplemente: en Python 2, puede almacenar cadenas en 2 tipos diferentes.
El primero es ASCII, que es de tipo str en python, utiliza 1 byte de memoria. (256 caracteres, almacenará mayormente alfabetos en inglés y símbolos simples)
El segundo tipo es UNICODE, que es un tipo Unicode 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 preferirá el tipo str pero si desea almacenar cadenas en tipo Unicode puede poner u delante del texto como u''text '' o puede hacerlo llamando a unicode ('' texto '')
Así que u es solo una forma corta de llamar a una función para convertir str en unicode . ¡Eso es!
Ahora, en la parte r , colóquela delante del texto para decirle a la computadora que el texto es texto en bruto, 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 formato 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. Entonces este código producirá error: r ''/'
Para almacenar una barra invertida (solo una), debe usar ''//'
Si desea almacenar más de 1 caracteres, puede seguir utilizando r como r ''//' producirá 2 barras invertidas como esperaba.
No sé la razón por la que r no funciona con un solo almacenamiento de barra invertida, pero la razón aún no está descrita por nadie. Espero que sea un error.
Realmente no hay ninguna " cadena cruda"; hay literales de cadena en bruto, que son exactamente los literales de cadena marcados con una ''r''
antes de la cita inicial.
Un "literal de cadena sin formato" es una sintaxis ligeramente diferente para un literal de cadena, en el que una barra invertida, /
, se toma como que significa "solo una barra invertida" (excepto cuando aparece justo antes de una cita que de otra manera terminaría el literal) - no hay "secuencias de escape" que representen nuevas líneas, tabulaciones, espacios de retroceso, feeds de formularios, etc. En los literales de cadena normales, cada barra invertida debe duplicarse para evitar que se tome como el inicio de una secuencia de escape.
Esta variante de sintaxis existe principalmente porque la sintaxis de los patrones de expresión regular está cargada de barras invertidas (pero nunca al final, por lo que la cláusula de "excepción" no importa) y se ve un poco mejor cuando se evita duplicar cada una de ellas. - eso es todo. También ganó cierta popularidad al expresar las rutas de archivos nativas de Windows (con barras diagonales inversas en lugar de barras diagonales como en otras plataformas), pero rara vez se necesita (ya que las barras diagonales normales también funcionan bien en Windows) e imperfectas (debido a la cláusula "excepto" encima).
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 pronto).
No está seguro de lo que quiere decir con " retroceder "; no hay direcciones intrínsecamente hacia atrás y hacia adelante, porque no hay un tipo de cadena sin formato, es solo una sintaxis alternativa para expresar los objetos de cadena perfectamente normales, bytes o unicode, como pueden ser.
Y sí, en Python 2. *, u''...''
es, por supuesto, siempre distinto de solo ''...''
: el primero es una cadena Unicode, el último es una cadena de bytes. En qué codificación se puede expresar el literal es un problema completamente ortogonal.
Por ejemplo, considere (Python 2.6):
>>> sys.getsizeof(''ciao'')
28
>>> sys.getsizeof(u''ciao'')
34
El objeto Unicode, por supuesto, ocupa más espacio en la memoria (una diferencia muy pequeña para una cadena muy corta, obviamente ;-).
Tal vez esto sea obvio, tal vez no, pero puede hacer 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
Un prefijo "u" denota que el valor tiene tipo unicode
lugar de str
.
Los literales de cadena sin formato, con un prefijo "r", escapan de las secuencias de escape dentro de ellos, por lo que len(r"/n")
es 2. Debido a que escapan a las secuencias de escape, no puede terminar un literal de cadena con una sola barra invertida: eso no es un 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"
r"/n"
son valores idénticos, al igual que 32
, 0x20
y 0b100000
son idénticos.
Puedes tener unicode literales crudos de cadena:
>>> 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, de lo contrario no afecta a las expresiones ni a los tipos. Sin embargo, se recommended evitar el código donde una codificación diferente 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 una cadena de documentación necesite mencionar un nombre de autor que requiera Latin-1; de lo contrario, usar / x, / u o / U escapes es la forma preferida de incluir datos no ASCII en literales de cadena.