在Python函数中,多行字符串的正确缩进是什么?
def method():
string = """line one
line two
line three"""
或者 def method():
string = """line one
line two
line three"""
还是其他什么?
在第一个示例中,字符串悬挂在函数外部看起来有点奇怪。
"""
对齐。def foo():
string = """line one
line two
line three"""
def foo():
string = ("this is an "
"implicitly joined "
"string")
textwrap
模块或者在PEP 257中介绍的处理文档字符串的技术。def trim(docstring):
import sys
if not docstring:
return ''
# Convert tabs to spaces (following the normal Python rules)
# and split into a list of lines:
lines = docstring.expandtabs().splitlines()
# Determine minimum indentation (first line doesn't count):
indent = sys.maxint
for line in lines[1:]:
stripped = line.lstrip()
if stripped:
indent = min(indent, len(line) - len(stripped))
# Remove indentation (first line is special):
trimmed = [lines[0].strip()]
if indent < sys.maxint:
for line in lines[1:]:
trimmed.append(line[indent:].rstrip())
# Strip off trailing and leading blank lines:
while trimmed and not trimmed[-1]:
trimmed.pop()
while trimmed and not trimmed[0]:
trimmed.pop(0)
# Return a single string:
return '\n'.join(trimmed)
string
更改为 text
或其他长度不同的名称,那么您现在需要更新多行字符串的每一行缩进才能使其正确地匹配 """
。 缩进策略不应该使未来的重构/维护变得复杂,这也是PEP失败的地方之一。 - kevlarrtextwrap.dedent
函数允许我们在源代码中使用正确的缩进,然后在使用之前将其删除。
正如其他人指出的那样,这是对字面值的额外函数调用;在决定将这些字面值放置在代码中的位置时,请考虑这一点。
import textwrap
def frobnicate(param):
""" Frobnicate the scrognate param.
The Weebly-Ruckford algorithm is employed to frobnicate
the scrognate to within an inch of its life.
"""
prepare_the_comfy_chair(param)
log_message = textwrap.dedent("""\
Prepare to frobnicate:
Here it comes...
Any moment now.
And: Frobnicate!""")
weebly(param, log_message)
ruckford(param)
Prepare to frobnicate:
Here it comes...
Any moment now.
And: Frobnicate!
textwrap.dedent()
函数调用的结果与输入参数一样都是一个常量值。 - martineau然后下一行
foo.x = textwrap.dedent("bar")`。 - n611x007inspect.cleandoc
的方式如下:import inspect
def method():
string = inspect.cleandoc("""
line one
line two
line three""")
inspect.cleandoc
从 Python 2.6 开始就存在了,那是在 2008。这绝对是最干净的答案,特别是它不使用悬挂缩进风格,这只会浪费不必要的空间。 - kevlarr其他答案好像都没有提到 (只有 naxa 在评论中深入提到) 的一个选项是:
def foo():
string = ("line one\n" # Add \n in the string
"line two" "\n" # Add "\n" after the string
"line three\n")
这将允许正确对齐、隐式地连接行,并仍然保留换行符号,对我来说,这是使用多行字符串的原因之一。
它不需要任何后处理,但您需要在任何需要换行的位置手动添加 \n
。可以内联或作为单独的字符串添加。后者更容易复制粘贴。
black
格式化时(第一个字符串段落在新行上,并在括号之后的下一个缩进处对齐),比答案中显示的效果更好,可以为更长的字符串提供更多的行长度。 - undefined更多选项。在启用pylab的Ipython中,dedent已经在命名空间中了。我检查过它是来自matplotlib的。或者可以使用以下方式导入:
一些更多的选项。在启用pylab的Ipython中,dedent已经被引入命名空间。我检查过它是由matplotlib提供的。或者可以通过以下方式导入:
from matplotlib.cbook import dedent
文档中指出它比textwrap的等效物更快,在我的IPython测试中,平均确实比textwrap快3倍。 它还有一个好处,就是丢弃任何前导空行,这使您在构建字符串时具有灵活性:
"""
line 1 of string
line 2 of string
"""
"""\
line 1 of string
line 2 of string
"""
"""line 1 of string
line 2 of string
"""
使用matplotlib的dedent函数会给这三个例子带来相同的合理结果。textwrap的dedent函数将在第一个例子中有一个前导空行。
显而易见的缺点是textwrap在标准库中,而matplotlib是外部模块。
在这里需要做一些权衡… dedent函数使您的代码更易读,在定义字符串的地方,但需要稍后处理才能获得可用格式的字符串。在文档字符串中,显而易见的是应该使用正确的缩进,因为大多数文档字符串的用途都会进行所需的处理。
当我需要在我的代码中使用非长字符串时,我发现以下代码确实很丑陋,其中我让长字符串跳出封闭缩进。肯定无法满足"美丽胜于丑陋"的要求,但可以说它比dedent替代品更简单、更明确。
def example():
long_string = '''\
Lorem ipsum dolor sit amet, consectetur adipisicing
elit, sed do eiusmod tempor incididunt ut labore et
dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip.\
'''
return long_string
print example()
如果您想要一个快速且方便的解决方案,并且不想要自己输入换行符号,那么您可以选择使用列表,例如:
def func(*args, **kwargs):
string = '\n'.join([
'first line of very long string and',
'second line of the same long thing and',
'third line of ...',
'and so on...',
])
print(string)
return
sep
参数设置为'\n'
比使用join
函数更加简洁。 - undefinedI prefer
def method():
string = \
"""\
line one
line two
line three\
"""
或者
def method():
string = """\
line one
line two
line three\
"""
我的建议是,为了获得缩进,请转义换行符:
def foo():
return "{}\n"\
"freq: {}\n"\
"temp: {}\n".format( time, freq, temp )
我来到这里是为了寻找一个简单的一行代码,可以移除/纠正文档字符串的缩进级别以便打印,而不会让它看起来凌乱,例如通过在脚本中使其“悬挂在函数外部”。
以下是我最终采取的方法:
import string
def myfunction():
"""
line 1 of docstring
line 2 of docstring
line 3 of docstring"""
print str(string.replace(myfunction.__doc__,'\n\t','\n'))[1:]
显然,如果你是用空格(例如4个)而不是制表符进行缩进,请使用类似于这样的东西:
print str(string.replace(myfunction.__doc__,'\n ','\n'))[1:]
如果你喜欢这样的文档字符串,那么你就不需要删除第一个字符:
"""line 1 of docstring
line 2 of docstring
line 3 of docstring"""
print string.replace(myfunction.__doc__,'\n\t','\n')
print string.lstrip()
method.__doc__
和任何其他str
字面值一样,并不会被 Python 自身修改。 - c z