¿Cómo eliminar la sangría extra de las cadenas multilínea de Python triple comited?

StackOverflow https://stackoverflow.com/questions/1412374

  •  05-07-2019
  •  | 
  •  

Pregunta

Tengo un editor de python en el que el usuario ingresa un script o código, que luego se coloca en un método principal entre bambalinas, al tiempo que todas las líneas están sangradas. El problema es que si un usuario tiene una cadena de varias líneas, la sangría hecha a todo el script afecta a la cadena, insertando una pestaña en cada espacio. Un script de problema sería algo tan simple como:

"""foo
bar
foo2"""

Entonces, cuando en el método principal se vería así:

def main():
    """foo
    bar
    foo2"""

y la cadena ahora tendría una pestaña adicional al comienzo de cada línea.

¿Fue útil?

Solución

Entonces, si lo consigo correctamente, tomas lo que sea que el usuario ingresa, lo sangras correctamente y lo agregas al resto de tu programa (y luego ejecutas todo el programa).

Entonces, después de poner la entrada del usuario en su programa, podría ejecutar una expresión regular, que básicamente elimina esa sangría forzada. Algo así como: Dentro de tres comillas, reemplaza todos los " nuevos marcadores de línea " seguido de cuatro espacios (o una pestaña) con solo un " marcador de línea nueva " ;.

Otros consejos

textwrap.dedent de la biblioteca estándar está ahí para deshacerlo automáticamente La sangría loca.

Por lo que veo, una mejor respuesta aquí podría ser inspect.cleandoc , que hace funcionalmente lo que textwrap.dedent hace, pero también soluciona los problemas que textwrap .dedent tiene con la línea principal. El siguiente ejemplo muestra las diferencias:

   >>> import textwrap
   >>> import inspect
   >>> x = """foo bar
       baz
       foobar
       foobaz
       """
   >>> inspect.cleandoc(x)
   'foo bar\nbaz\nfoobar\nfoobaz'
   >>> textwrap.dedent(x)
   'foo bar\n    baz\n    foobar\n    foobaz\n'
   >>> y = """
   ...     foo
   ...     bar
   ... """
   >>> textwrap.dedent(y)
   '\nfoo\nbar\n'
   >>> inspect.cleandoc(y)
   'foo\nbar'

Lo que sigue a la primera línea de una cadena multilínea es parte de la cadena y no se trata como sangría por el analizador. Puedes escribir libremente:

def main():
    """foo
bar
foo2"""
    pass

y hará lo correcto.

Por otro lado, eso no es legible, y Python lo sabe. Por lo tanto, si una cadena de documentos contiene espacios en blanco en su línea segunda , esa cantidad de espacios en blanco se eliminará cuando use help () para ver la cadena de documentos. Por lo tanto, help (main) y el siguiente help (main2) producen la misma información de ayuda.

def main2():
    """foo
    bar
    foo2"""
    pass

La única manera que veo - es quitar las primeras n pestañas para cada línea que comienza con la segunda, donde n es la identificación conocida del método principal.

Si esa identificación no se conoce de antemano, puede agregar una nueva línea final antes de insertarla y quitar el número de pestañas de la última línea ...

La tercera solución es analizar los datos y encontrar el comienzo de una cita multilínea y no agregar su identificación a cada línea después de que se cierre.

Creo que hay una mejor solución ..

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top