web-dev-qa-db-fra.com

Comment supprimer une indentation supplémentaire de Python Triple Triple Cording Strings Multi-Line?

J'ai un python éditeur où l'utilisateur entre dans un script ou un code, qui est ensuite mis dans une méthode principale dans les coulisses, tout en ayant également une ligne en retrait. Le problème est que si un utilisateur A une chaîne multi-lignes, l'indentation apportée à l'ensemble du script affecte la chaîne en insérant une languette dans chaque espace. Un script de problème serait aussi simple que:

"""foo
bar
foo2"""

Donc, quand dans la méthode principale, il ressemblerait à:

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

et la chaîne aurait désormais un onglet supplémentaire au début de chaque ligne.

55
Mike

textwrap.dedent de la bibliothèque standard est là pour annuler automatiquement l'indentation Wacky.

103
thraxil

D'après ce que je vois, une meilleure réponse ici pourrait être inspect.cleandoc, qui fait fonctionnellement ce que textwrap.dedent fait mais corrige également les problèmes que textwrap.dedent a avec la ligne de langue.

L'exemple ci-dessous montre les différences:

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

Ce qui suit la première ligne d'une chaîne multiligne fait partie de la chaîne et non traitée comme indentation par l'analyseur. Vous pouvez écrire librement:

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

et cela fera la bonne chose.

D'autre part, ce n'est pas lisible, et Python====== le connaît. Donc, si une DOCSTRING contient des espaces dans sa qualité deuxième ligne, ce montant de WhitSpace est dépouillé lorsque vous Utilisez help() pour voir la docstring. Ainsi, help(main) et le bas help(main2) produisent les mêmes informations d'aide.

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

Montrant la différence entre textwrap.dedent et inspect.cleandoc Avec un peu plus de clarté:

Comportement avec la partie principale non indentée

import textwrap
import inspect

string1="""String
with
no indentation
       """
string2="""String
        with
        indentation
       """
print('string1 plain=' + repr(string1))
print('string1 inspect.cleandoc=' + repr(inspect.cleandoc(string1)))
print('string1 texwrap.dedent=' + repr(textwrap.dedent(string1)))
print('string2 plain=' + repr(string2))
print('string2 inspect.cleandoc=' + repr(inspect.cleandoc(string2)))
print('string2 texwrap.dedent=' + repr(textwrap.dedent(string2)))

Sortir

string1 plain='String\nwith\nno indentation\n       '
string1 inspect.cleandoc='String\nwith\nno indentation\n       '
string1 texwrap.dedent='String\nwith\nno indentation\n'
string2 plain='String\n        with\n        indentation\n       '
string2 inspect.cleandoc='String\nwith\nindentation'
string2 texwrap.dedent='String\n        with\n        indentation\n'

Comportement avec la partie la plus ancrée en retrait

string1="""
String
with
no indentation
       """
string2="""
        String
        with
        indentation
       """

print('string1 plain=' + repr(string1))
print('string1 inspect.cleandoc=' + repr(inspect.cleandoc(string1)))
print('string1 texwrap.dedent=' + repr(textwrap.dedent(string1)))
print('string2 plain=' + repr(string2))
print('string2 inspect.cleandoc=' + repr(inspect.cleandoc(string2)))
print('string2 texwrap.dedent=' + repr(textwrap.dedent(string2)))

Sortir

string1 plain='\nString\nwith\nno indentation\n       '
string1 inspect.cleandoc='String\nwith\nno indentation\n       '
string1 texwrap.dedent='\nString\nwith\nno indentation\n'
string2 plain='\n        String\n        with\n        indentation\n       '
string2 inspect.cleandoc='String\nwith\nindentation'
string2 texwrap.dedent='\nString\nwith\nindentation\n'
0
codeforester