2010-05-20 43 views
23

Me encontré con algo que hace mucho tiempo y me pregunté si se trataba de un "error" o al menos un error de Python. Tengo curiosidad si alguien sabe de alguna justificación para este comportamiento. Pensé en leer ahora "Code Like a Pythonista", que hasta ahora ha sido agradable. Solo estoy familiarizado con la línea 2.x de Python.Cadenas de Python raw y barra diagonal inversa

Las cadenas sin formato son cadenas que llevan el prefijo r. Esto es genial porque puedo usar barras diagonales inversas en expresiones regulares y no necesito duplicar todo en todas partes. También es útil para escribir scripts desechables en Windows, así que también puedo usar barras diagonales inversas. (Sé que también puedo usar barras diagonales, pero las secuencias de comandos desechables a menudo contienen contenido cortado & pegado de otra parte en Windows.)

¡Tan bueno! A menos que, por supuesto, realmente quieras que tu cadena termine con una barra invertida. No hay forma de hacerlo en una cadena 'en bruto'.

In [9]: r'\n' 
Out[9]: '\\n' 

In [10]: r'abc\n' 
Out[10]: 'abc\\n' 

In [11]: r'abc\' 
------------------------------------------------ 
    File "<ipython console>", line 1 
    r'abc\' 
     ^
SyntaxError: EOL while scanning string literal 


In [12]: r'abc\\' 
Out[12]: 'abc\\\\' 

Así que una barra invertida antes de la cotización de cierre es un error, sino dos barras invertidas le da dos barras invertidas! Ciertamente, no soy el único que está molesto por esto?

¿Por qué las cadenas de caracteres 'en bruto' están 'en bruto, excepto para la comilla inversa'? Quiero decir, si quisiera insertar una única cita allí, simplemente usaría comillas dobles alrededor de la cadena, y viceversa. Si quisiera las dos, solo triplicaría la cita. Si realmente quisiera tres citas seguidas en una cadena en bruto, bueno, supongo que tendría que tratar, pero ¿se considera esto un "comportamiento correcto"?

Esto es particularmente problemático con los nombres de carpeta en Windows, donde la barra diagonal inversa es el delímetro de ruta.

Respuesta

18

Es un FAQ.

Y en respuesta a "realmente desea que su cadena termine con una barra diagonal inversa. No hay forma de hacerlo en una cadena 'en bruto'": la pregunta frecuente muestra cómo solucionarlo.

>>> r'ab\c' '\\' == 'ab\\c\\' 
True 
>>> 
+4

parece ciertamente como un misfeature. –

+3

@DS: ¿Su diseño alternativo sugerido para cadenas sin formato es ...? –

+2

No sabía que era una pregunta frecuente, pero probablemente debería haberlo supuesto. ;) No estoy hablando de @DS, pero mi diseño alternativo es "sin procesamiento de escape". ¿Sabes algo así como lo que dice en la lata? –

4

Las cadenas sin formato se usan principalmente para escribir de forma legible los patrones para las expresiones regulares, que nunca necesitan una barra invertida final; es un accidente que pueden ser útiles para Windows (donde podría usar barras diagonales en la mayoría de los casos de todos modos: la biblioteca Microsoft C que subyace a Python acepta cualquiera de las dos formas). No se considera aceptable hacer que (casi) sea imposible escribir un patrón de expresión regular que contenga comillas dobles simples y, solo para reforzar el accidente en cuestión.

("Casi" porque la cotización triple casi siempre ayudaría ... pero a veces podría ser un poco molesto).

Así que, sí, cuerdas primas fueron diseñados para comportarse de esa manera (que prohíbe un número impar de barras invertidas de cola), y es considera perfectamente "comportamiento adecuado" para que se respeten las decisiones de diseño Guido hizo cuando los inventó; -).

+0

Sí, abordé la razón por la que estoy usando barras diagonales inversas en mi OP. Gracias sin embargo; mi punto era exactamente que las cotizaciones triples superarían cualquier problema con el uso de caracteres de comillas en expresiones regulares. De hecho, quería tener una barra inclinada invertida pero nunca una expresión regular con varios tipos diferentes de comillas. –

+0

Esto continúa confundiendo mi mente por qué esto es una cosa. La razón declarada de que "es la única manera de tener comillas simples y dobles en la cadena" no responde porque siempre debe tener una barra diagonal inversa antes de esta comilla necesaria y esa barra invertida persiste en la cadena compilada. No hay forma de que pueda ver para crear una cadena que contenga solo comillas simples y dobles, salvo la triple cita. –

+0

Ojalá pudiera votar más esto. Creo que el comportamiento es extrañamente inconsistente, pero esta respuesta da algunos indicios de por qué el comportamiento es extrañamente inconsistente. –

0

Pensamientos sobre por qué 'raw' strings son 'raw, excepto para la comilla inversa'? I significa, si quisiera insertar una comilla simple allí, simplemente usaría comillas dobles alrededor de la cadena, y viceversa.

Pero eso plantearía la pregunta de por qué las cadenas sin formato son 'crudas, excepto las comillas incrustadas?'

Tiene que tener mecanismo de escape, de lo contrario, nunca podrá usar los caracteres de comillas exteriores dentro de la cadena. Y luego necesitas un mecanismo de escape para el mecanismo de escape.

+0

La regla "no se puede usar el carácter de comillas circundante en la cadena" parece fácil de seguir y muy pragmática. En el caso excepcionalmente raro de que necesite los cuatro de comillas simples, comillas dobles, comillas simples triples y comillas dobles triplicadas, creo que no es demasiado fuera de línea decir que no todas pueden aparecer en una cadena continua continua. Cuando quiero una cadena en bruto, no quiero escapes, por lo que parece estúpido tener un escape en una ubicación en una cadena sin procesar que luego causa un error. –

+0

@ dash-tom-bang Esa regla le impide usar ese carácter * en absoluto. * Cualquier regla que no tenga esa restricción es mejor que cualquier regla que lo haga. – EJP

+0

Si la alternativa es que no puede hacer otra cosa que pueda desear hacer (por ejemplo, "tener una barra diagonal inversa"), la respuesta no es tan blanca y negra. "Es una cadena en bruto, excepto ..." viola el deseo de "hacer lo obvio"; las excepciones a las reglas deben evitarse cuando sea posible. –

3

Otra forma de solucionar esto es:

>>> print r"Raw \with\ trailing backslash\\"[:-1] 
Raw \with\ trailing backslash\ 
Cuestiones relacionadas