Pergunta

Eu tenho um editor do Python onde o usuário está inserindo um script ou código, que é colocado em um método principal nos bastidores, além de ter todas as linhas recuadas. O problema é que, se um usuário tiver uma string multi -linha, o recuo feito em todo o script afeta a string, inserindo uma guia em todos os espaço. Um script de problema seria algo tão simples como:

"""foo
bar
foo2"""

Então, quando no método principal seria:

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

E a string agora teria uma guia extra no início de todas as linhas.

Foi útil?

Solução

Portanto, se eu o obtiver corretamente, você pega as que o usuário entra, recupere -o corretamente e adicione -o ao restante do seu programa (e execute todo esse programa).

Então, depois de colocar a entrada do usuário em seu programa, você pode executar um regex, que basicamente leva esse recuo forçado de volta. Algo como: Dentro de três citações, substitua todos os "novos marcadores de linha" seguidos por quatro espaços (ou uma guia) por apenas um "novo marcador de linha".

Outras dicas

textwrap.dedent A partir da biblioteca padrão, existe para desfazer automaticamente o recuo maluco.

Pelo que vejo, uma resposta melhor aqui pode ser inspect.cleandoc, que faz funcionalmente o que textwrap.dedent mas também corrige os problemas que textwrap.dedent tem com a linha principal. O exemplo abaixo mostra as diferenças:

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

O que se segue à primeira linha de uma corda multilina faz parte da string e não é tratada como indentação pelo analisador. Você pode escrever livremente:

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

E isso fará a coisa certa.

Por outro lado, isso não é legível, e Python sabe disso. Então, se um docstring contém espaço em branco em seu segundo linha, essa quantidade de espaço em branco é despojada quando você usa help() para ver o docstring. Desta forma, help(main) e o abaixo help(main2) produzir as mesmas informações de ajuda.

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

A única maneira que vejo - é tirar as primeiras guias N para cada linha que começa com a segunda, onde n é a identificação conhecida do método principal.

Se essa identificação não for conhecida de antemão - você pode adicionar a Newline à direita antes de inseri -la e desmaiar o número de guias da última linha ...

A terceira solução é analisar os dados e encontrar o início da cotação multilina e não adicionar sua identificação a todas as linhas depois que ela será fechada.

Acho que há uma solução melhor ..

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top