2010-06-03 16 views
20

According to the docs, la cadena de codificación incorporado string_escape:Python "string_escape" vs "unicode_escape"

Produce [s] una cadena que es adecuado como cadena literal en el código fuente de Python

... mientras que el unicode_escape:

Produce [s] una cadena que es adecuado como Unicode literal en el código fuente Python

Por lo tanto, deberían tener más o menos el mismo comportamiento. PERO, aparecen para tratar de manera diferente entre comillas simples:

>>> print """before '" \0 after""".encode('string-escape') 
before \'" \x00 after 
>>> print """before '" \0 after""".encode('unicode-escape') 
before '" \x00 after 

El string_escape escapa a la comilla simple mientras que el Unicode no lo hace. ¿Es seguro asumir que puedo simplemente:

>>> escaped = my_string.encode('unicode-escape').replace("'", "\\'") 

... y obtener el comportamiento esperado?

Editar: Para ser súper claro, el comportamiento esperado es obtener algo adecuado como un literal.

Respuesta

19

De acuerdo con mi interpretación de la implementación de unicode-escape y el unicode repr en la fuente CPython 2.6.5, sí; la única diferencia entre repr(unicode_string) y unicode_string.encode('unicode-escape') es la inclusión de las citas de ajuste y el escape de la cotización que se utilizó.

Ambos son impulsados ​​por la misma función, unicodeescape_string. Esta función toma un parámetro cuya única función es alternar la adición de las comillas de ajuste y el escape de esa cita.

+0

Esta ha sido la respuesta más clara a algún error unicode 'secuencia de escape Unicode no soportada' ¡Incluso funciona en 2016! ¡Gracias! – dotslash

10

Dentro del rango 0 ≤ c < 128, sí, el ' es la única diferencia para CPython 2.6.

>>> set(unichr(c).encode('unicode_escape') for c in range(128)) - set(chr(c).encode('string_escape') for c in range(128)) 
set(["'"]) 

Fuera de este rango, los dos tipos no son intercambiables.

>>> '\x80'.encode('string_escape') 
'\\x80' 
>>> '\x80'.encode('unicode_escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
UnicodeDecodeError: 'ascii' codec can’t decode byte 0x80 in position 0: ordinal not in range(128) 

>>> u'1'.encode('unicode_escape') 
'1' 
>>> u'1'.encode('string_escape') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: escape_encode() argument 1 must be str, not unicode 

En Python 3.x, la codificación string_escape ya no existe, ya que sólo puede almacenar str Unicode.

+1

Eso es simplemente porque '\ x80' no es una cadena codificada ascii válida. Pruebe 'u '\ x80'.encode (' unicode-escape ')' y obtendrá '' \\ x80'' –

+0

@Mike: ¿Pero su' my_string' es 'str' o' unicode'? – kennytm