如何删除Python三引号多行字符串的额外缩进?

58 python quotes strip multiline

我有一个python编辑器,用户输入一个脚本或代码,然后将其放入幕后的main方法中,同时还缩进每一行.问题是如果用户有多行字符串,则通过在每个空格中插入制表符,对整个脚本的缩进会影响字符串.问题脚本将是如此简单:

"""foo
bar
foo2"""
Run Code Online (Sandbox Code Playgroud)

所以当在main方法中它看起来像:

def main():
    """foo
    bar
    foo2"""
Run Code Online (Sandbox Code Playgroud)

并且字符串现在在每行的开头都有一个额外的制表符.

thr*_*xil 108

标准库中的textwrap.dedent可以自动撤消古怪的缩进.

  • 请注意,如果第一行以"""foo"开头,则第一行缺少其他行所具有的前导缩进,因此`dedent`将不会执行任何操作.如果您等待启动foo,它将起作用下一行并转义第一个换行符:`"""\"` (10认同)
  • 标准库永远不会出现意外. (6认同)
  • 为了解决@ScottH 提到的缺点,请参阅我关于`inspect.cleandoc` 的回答 (3认同)

bbe*_*e10 29

从我看到的,这里可能会有一个更好的答案inspect.cleandoc,它在功能上做了什么textwrap.dedent,但也解决了textwrap.dedent与领先线有关的问题.以下示例显示了差异:

>>> 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'
>>> z = """\tfoo
bar\tbaz
"""
>>> textwrap.dedent(z)
'\tfoo\nbar\tbaz\n'
>>> inspect.cleandoc(z)
'foo\nbar     baz'
Run Code Online (Sandbox Code Playgroud)

  • 请注意,否则这两者并不完全相同,并且 cleandoc 执行的处理不仅仅是删除缩进。至少,将 '\t'` 扩展为 '' '` (3认同)
  • 还可以使用“textwrap.dedent(s).strip()”来避免更改制表符并仍然处理前导和尾随换行符。 (3认同)

Sin*_*ion 17

多行字符串的第一行后面的内容是字符串的一部分,并且不被解析器视为缩进.你可以随意写:

def main():
    """foo
bar
foo2"""
    pass
Run Code Online (Sandbox Code Playgroud)

它会做正确的事情.

另一方面,这是不可读的,Python知道它.因此,如果文档字符串在其第二行中包含空格,则在help()用于查看文档字符串时会删除该数量的空白.因此,help(main)以下help(main2)产生相同的帮助信息.

def main2():
    """foo
    bar
    foo2"""
    pass
Run Code Online (Sandbox Code Playgroud)


Flo*_*anH -15

因此,如果我正确理解,您将获取用户输入的所有内容,正确缩进并将其添加到程序的其余部分(然后运行整个程序)。

因此,将用户输入放入程序后,您可以运行正则表达式,这基本上会恢复强制缩进。类似于:在三个引号内,将所有“换行标记”后跟四个空格(或制表符)替换为仅一个“换行标记”。

  • @thraxil 建议使用 textwrap.dedent 是可行的方法。考虑更改您接受的答案。 (25认同)
  • @ChrisCalo @bbenne10 的答案更好 (3认同)