我有一个python编辑器,用户在其中输入脚本或代码,然后将其放入幕后的主要方法中,同时每行缩进。问题是,如果用户具有多行字符串,则通过在每个空格中插入制表符,对整个脚本进行的缩进会影响字符串。问题脚本非常简单,例如:
"""foo
bar
foo2"""
因此,在main方法中,它看起来像:
def main():
"""foo
bar
foo2"""
并且该字符串现在在每一行的开头都有一个额外的制表符。
我有一个python编辑器,用户在其中输入脚本或代码,然后将其放入幕后的主要方法中,同时每行缩进。问题是,如果用户具有多行字符串,则通过在每个空格中插入制表符,对整个脚本进行的缩进会影响字符串。问题脚本非常简单,例如:
"""foo
bar
foo2"""
因此,在main方法中,它看起来像:
def main():
"""foo
bar
foo2"""
并且该字符串现在在每一行的开头都有一个额外的制表符。
Answers:
因此,如果我正确理解它,则可以接受用户输入的任何内容,对其进行适当的缩进,然后将其添加到程序的其余部分中(然后运行整个程序)。
因此,在将用户输入放入程序后,您可以运行正则表达式,基本上可以将强制缩回。诸如此类:在三引号中,将所有“换行标记”替换为四个空格(或制表符),仅用“换行标记”代替。
从我的角度来看,这里可能是一个更好的答案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'
请注意,这inspect.cleandoc
还会将内部制表符扩展为空格。这可能不适合一个人的用例,但对我来说很好。
'\t'
至' '
多行字符串的第一行之后的内容是字符串的一部分,解析器未将其视为缩进。您可以自由地写:
def main():
"""foo
bar
foo2"""
pass
它会做正确的事。
另一方面,这是不可读的,Python知道这一点。因此,如果文档字符串的第二行中包含空格,则当您用于help()
查看文档字符串时,该空格量会被剥离。因此,help(main)
下面的代码会help(main2)
产生相同的帮助信息。
def main2():
"""foo
bar
foo2"""
pass
help()
默认情况下使事情变得更好的用例。要在其他地方使用相同的确定逻辑,您可以使用textwrap.dedent()
此问题的其他答案中所述的方法。
我看到的唯一方法是-从第二行开始为每行剥离前n个制表符,其中n是main方法的已知标识。
如果该标识是事先未知的-您可以在插入尾随换行符之前添加尾随换行符,并从最后一行删除标签的数量...
第三种解决方案是解析数据并找到多行引号的开头,并且不要在之后将您的标识添加到每一行,直到将其关闭为止。
认为有更好的解决方案。
显示之间的差别textwrap.dedent
和inspect.cleandoc
用少许更加清晰:
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)))
输出量
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'
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)))
输出量
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'