python unicode future-proof

python - (error de Unicode) el codec ''unicodeescape'' no puede decodificar bytes-cadena con ''/ u''



future-proof (4)

AFAIK, todo lo que hace from __future__ import unicode_literals es hacer que todos los literales de cadena sean de tipo Unicode, en lugar del tipo de cadena. Es decir:

>>> type('''') <type ''str''> >>> from __future__ import unicode_literals >>> type('''') <type ''unicode''>

Pero str y unicode siguen siendo tipos diferentes, y se comportan como antes.

>>> type(str('''')) <type ''str''>

Siempre, es de tipo str .

Sobre tu problema r''/u'' , es por diseño, ya que es equivalente a ru ''/ u'' sin unicode_literals . De la documentación:

Cuando se usa un prefijo ''r'' o ''R'' junto con un prefijo ''u'' o ''U'', las secuencias de escape / uXXXX y / UXXXXXXXX se procesan mientras que todas las demás barras invertidas se dejan en la cadena.

Probablemente por la forma en que el analizador léxico funcionó en la serie python2. En Python3 funciona como tú (y yo) esperaríamos.

Puede escribir la barra diagonal inversa dos veces y luego /u no se interpretará, ¡pero obtendrá dos barras diagonales inversas!

Las barras invertidas se pueden escapar con una barra diagonal anterior; Sin embargo, ambos permanecen en la cadena.

>>> ur''//u'' u''////u''

Así que en mi humilde opinión, tienes dos opciones simples:

  • No use cadenas sin procesar, y evite las barras invertidas (compatibles con python3):

    ''H://unittests''

  • Sea demasiado inteligente y aproveche los puntos de código de Unicode ( no compatibles con python3):

    r''H:/u005cunittests''

Escribiendo mi código para Python 2.6, pero teniendo en cuenta Python 3, pensé que era una buena idea poner

from __future__ import unicode_literals

En la parte superior de algunos módulos. En otras palabras, estoy pidiendo problemas (para evitarlos en el futuro), pero es posible que me falten algunos conocimientos importantes aquí. Quiero poder pasar una cadena que representa una ruta de archivo y crear una instancia de un objeto tan simple como

MyObject(''H:/unittests'')

En Python 2.6 , esto funciona bien, no es necesario usar barras invertidas dobles o una cadena sin formato, incluso para un directorio que comience con ''/u..'' , que es exactamente lo que quiero. En el método __init__ me aseguro de que todas las ocurrencias individuales se interpreten como '' // '', incluidos aquellos antes de los caracteres especiales como en /a , /b , /f , /n , /r , /t y /v (solo /x sigue siendo un problema). También la decodificación de la cadena dada en Unicode usando la codificación (local) funciona como se espera.

Preparándose para Python 3.x , simulando mi problema real en un editor (comenzando con una consola limpia en Python 2.6), sucede lo siguiente:

>>> ''/u'' ''//u'' >>> r''/u'' ''//u''

(OK hasta aquí: ''/u'' está codificado por la consola usando la codificación local)

>>> from __future__ import unicode_literals >>> ''/u'' SyntaxError: (unicode error) ''unicodeescape'' codec can''t decode bytes in position 0-1: end of string in escape sequence

En otras palabras, la cadena (unicode) no se interpreta como unicode en absoluto, ni se descodifica automáticamente con la codificación local. Aun así para una cadena en bruto:

>>> r''/u'' SyntaxError: (unicode error) ''rawunicodeescape'' codec can''t decode bytes in position 0-1: truncated /uXXXX

lo mismo para u''/u'' :

>>> u''/u'' SyntaxError: (unicode error) ''unicodeescape'' codec can''t decode bytes in position 0-1: end of string in escape sequence

Además, esperaría que isinstance(str(''''), unicode) devuelva True (que no lo hace), porque la importación de unicode_literals debería hacer que todos los tipos de cadena sean unicode. (edit :) Debido a que en Python 3, todas las cadenas son secuencias de caracteres Unicode , yo esperaría que str('''')) devuelva tal unicode-string, y type(str('''')) sea ​​tanto <type ''unicode''> , y <type ''str''> (porque todas las cadenas son Unicode) pero también se dan cuenta de que <type ''unicode''> is not <type ''str''> . Confusión alrededor de ...

Preguntas

  • ¿Cómo puedo pasar mejor las cadenas que contienen '' /u ''? (sin escribir '' //u '')
  • ¿ from __future__ import unicode_literals realmente from __future__ import unicode_literals todos los cambios de Unicode relacionados con Python 3. para obtener un entorno completo de cadenas de Python 3?

edición: en Python 3, <type ''str''> es un objeto Unicode y <type ''unicode''> simplemente no existe. En mi caso, quiero escribir código para Python 2 (.6) que funcionará en Python 3. Pero cuando import unicode_literals , no puedo verificar si una cadena es de <type ''unicode''> porque:

  • Supongo que unicode no es parte del espacio de nombres
  • si unicode es parte del espacio de nombres, un literal de <type ''str''> aún es unicode cuando se crea en el mismo módulo
  • type(mystring) siempre devolverá <type ''str''> para literales Unicode en Python 3

Mis módulos locale.getdefaultlocale()[1] estar codificados en ''utf-8'' por un # coding: UTF-8 comentario de # coding: UTF-8 en la parte superior, mientras que mi locale.getdefaultlocale()[1] devuelve ''cp1252''. Entonces, si llamo a MyObject(''çça'') desde mi consola, se codifica como ''cp1252'' en Python 2, y en ''utf-8'' cuando se llama a MyObject(''çça'') desde el módulo. En Python 3, no se codificará, sino un literal Unicode.

editar:

Perdí la esperanza de que se me permitiera evitar el uso de ''/' antes de una u (o x para el caso). También entiendo las limitaciones de importar unicode_literals . Sin embargo, las muchas combinaciones posibles de pasar una cadena de un módulo a la consola y viceversa con cada codificación diferente, y además de importar unicode_literals o no y Python 2 vs Python 3, me dieron ganas de crear una visión general mediante pruebas reales . De ahí la tabla de abajo.

En otras palabras, type(str('''')) no devuelve <type ''str''> en Python 3, sino en <class ''str''> , y parece que se evitan todos los problemas de Python 2.


Cuando está escribiendo literales de cadena que contienen barras diagonales inversas, como rutas (en Windows) o expresiones regulares, use cadenas sin formato. Para eso están.


Intento esto en Python 3:

importación os

os.path.abspath ("yourPath")

y ha funcionado!


Para mí este problema relacionado con la versión no está actualizada, en este caso numpy

Arreglar :

conda install -f numpy