How to remove extra indentation of Python triple q

2019-01-30 23:54发布

I have a python editor where the user is entering a script or code, which is then put into a main method behind the scenes, while also having every line indented. The problem is that if a user has a multi line string, the indentation made to the whole script affects the string, by inserting a tab in every space. A problem script would be something so simple as:

"""foo
bar
foo2"""

So when in the main method it would look like:

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

and the string would now have an extra tab at the beginning of every line.

5条回答
贼婆χ
2楼-- · 2019-01-31 00:00

So if I get it correctly, you take whatever the user inputs, indent it properly and add it to the rest of your program (and then run that whole program).

So after you put the user input into your program, you could run a regex, that basically takes that forced indentation back. Something like: Within three quotes, replace all "new line markers" followed by four spaces (or a tab) with only a "new line marker".

查看更多
走好不送
3楼-- · 2019-01-31 00:02

What follows the first line of a multiline string is part of the string, and not treated as indentation by the parser. You may freely write:

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

and it will do the right thing.

On the other hand, that's not readable, and Python knows it. So if a docstring contains whitespace in it's second line, that amount of whitespace is stripped off when you use help() to view the docstring. Thus, help(main) and the below help(main2) produce the same help info.

def main2():
    """foo
    bar
    foo2"""
    pass
查看更多
你好瞎i
4楼-- · 2019-01-31 00:09

From what I see, a better answer here might be inspect.cleandoc, which does functionally what textwrap.dedent does but also fixes the problems that textwrap.dedent has with the leading line. The below example shows the differences:

   >>> 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'
查看更多
劫难
5楼-- · 2019-01-31 00:15

textwrap.dedent from the standard library is there to automatically undo the wacky indentation.

查看更多
唯我独甜
6楼-- · 2019-01-31 00:15

The only way i see - is to strip first n tabs for each line starting with second, where n is known identation of main method.

If that identation is not known beforehand - you can add trailing newline before inserting it and strip number of tabs from the last line...

The third solution is to parse data and find beginning of multiline quote and do not add your identation to every line after until it will be closed.

Think there is a better solution..

查看更多
登录 后发表回答