Come rimuovere il rientro aggiuntivo delle stringhe multilinea Python con virgolette triple?

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

  •  05-07-2019
  •  | 
  •  

Domanda

Ho un editor Python in cui l'utente sta inserendo uno script o un codice, che viene quindi inserito in un metodo principale dietro le quinte, pur avendo tutte le righe rientrate. Il problema è che se un utente ha una stringa a più righe, il rientro fatto all'intero script influenza la stringa, inserendo una scheda in ogni spazio. Uno script problematico sarebbe qualcosa di così semplice come:

"""foo
bar
foo2"""

Quindi quando nel metodo principale sembrerebbe:

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

e la stringa ora avrebbe una scheda aggiuntiva all'inizio di ogni riga.

È stato utile?

Soluzione

Quindi, se lo capisco correttamente, prendi qualunque input dell'utente, indentalo correttamente e lo aggiungi al resto del tuo programma (e poi esegui l'intero programma).

Quindi, dopo aver inserito l'input dell'utente nel programma, è possibile eseguire una regex, che sostanzialmente riprende quella rientranza forzata. Qualcosa di simile: tra tre virgolette, sostituisci tutti i "nuovi marcatori di linea" seguito da quattro spazi (o una scheda) con solo un "nuovo indicatore di linea".

Altri suggerimenti

textwrap.dedent dalla libreria standard è lì per annullare automaticamente la strana indentazione.

Da quello che vedo, una risposta migliore qui potrebbe essere inspect.cleandoc , che fa funzionalmente ciò che fa textwrap.dedent ma risolve anche i problemi che textwrap .dedent ha con la linea principale. L'esempio seguente mostra le differenze:

   >>> 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'

Ciò che segue la prima riga di una stringa multilinea fa parte della stringa e non viene trattato come rientro dal parser. Puoi scrivere liberamente:

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

e farà la cosa giusta.

D'altra parte, questo non è leggibile e Python lo sa. Quindi, se un docstring contiene spazi bianchi nella sua seconda riga, quella quantità di spazi bianchi viene rimossa quando si utilizza help () per visualizzare il docstring. Pertanto, help (main) e il help (main2) di seguito forniscono le stesse informazioni di aiuto.

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

L'unico modo in cui vedo - è di eliminare le prime n schede per ogni riga che inizia con la seconda, dove n è nota l'identificazione del metodo principale.

Se tale identificazione non è nota in anticipo, è possibile aggiungere una nuova riga finale prima di inserirla e rimuovere il numero di schede dall'ultima riga ...

La terza soluzione è analizzare i dati e trovare l'inizio del preventivo multilinea e non aggiungere la tua identificazione a ogni riga successiva fino a quando non verrà chiusa.

Pensa che ci sia una soluzione migliore ..

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top