如何在Python中进行换行(行延续)?

1362

假设:

e = 'a' + 'b' + 'c' + 'd'

如何将上述内容写成两行?

e = 'a' + 'b' +
    'c' + 'd'
10个回答

1529

什么是代码行?在下一行中只要有参数就不会有任何问题:

a = dostuff(blahblah1, blahblah2, blahblah3, blahblah4, blahblah5, 
            blahblah6, blahblah7)
否则,您可以像这样做:

否则,您可以这样处理:

if (a == True and
    b == False):

或者使用显式的换行符:

if a == True and \
   b == False:

查看风格指南以获取更多信息。

使用括号,您的示例可以写在多行中:

a = ('1' + '2' + '3' +
    '4' + '5')

通过显式换行符,也可以达到同样的效果:

a = '1' + '2' + '3' + \
    '4' + '5'

请注意,样式指南表示在括号的隐式续行符中使用是首选的,但在这种特定情况下,仅在表达式周围添加括号可能是错误的方法。


50
实际上,你完全颠倒了样式指南的偏好。隐式延续是首选方式,只有在必要时才使用显式反斜杠。 - Carl Meyer
39
卡尔:我不同意,这是来自指南的内容:“包装长行的首选方法是使用Python的括号、方括号和花括号中隐式的行续。如果需要,您可以在表达式周围添加一个额外的括号,但有时使用反斜杠看起来更好。” - Jerub
18
样式指南中的关键部分是“如果必要,您可以在表达式周围添加额外的一对括号,但有时使用反斜杠会更好看。” 样式指南并没有说您应该添加括号,而是留给作者自行决定。 - Tony Meyer
38
可以推测,自这些评论被添加以来,PEP-8已经发生了变化,因为现在很明显应该加上括号来包裹长行:“长行可以通过在表达式周围添加括号来跨多行进行换行。” - Daniel
66
确实,PEP8在2010年有所变化 - "有时使用反斜杠看起来更好"已经被删除。 - e100
显示剩余14条评论

305

PEP 8 -- Python代码风格指南中得知:

首选方法是使用Python中的括号、方括号和花括号来换行。可以通过在括号中包装表达式来将长行分成多行。这应该优先于使用反斜杠进行行连续。

有时仍然可以使用反斜杠。例如,长的多个with语句无法使用隐式连续性,因此可以接受使用反斜杠:

with open('/path/to/some/file/you/want/to/read') as file_1, \
     open('/path/to/some/file/being/written', 'w') as file_2:
     file_2.write(file_1.read())

Another such case is with assert statements.

请确保适当缩进延续的行。二元运算符的首选断行位置是在运算符之后而不是之前。以下是一些示例:
class Rectangle(Blob):

  def __init__(self, width, height,
                color='black', emphasis=None, highlight=0):
       if (width == 0 and height == 0 and
          color == 'red' and emphasis == 'strong' or
           highlight > 100):
           raise ValueError("sorry, you lose")
       if width == 0 and height == 0 and (color == 'red' or
                                          emphasis is None):
           raise ValueError("I don't think so -- values are %s, %s" %
                            (width, height))
       Blob.__init__(self, width, height,
                     color, emphasis, highlight)file_2.write(file_1.read())

PEP8现在推荐使用数学家及其出版商使用的相反约定(在二元操作符处换行)来提高可读性。

唐纳德·克努斯(Donald Knuth)的风格是在二元运算符之前换行,使运算符垂直对齐,从而减轻眼睛在确定哪些项目被加减时的工作量。

引自PEP8: 应该在二元运算符之前还是之后换行?

唐纳德·克努斯在他的《计算机和排版系列》中解释了传统规则:“虽然段落中的公式总是在二元运算和关系之后断开,但显示的公式总是在二元运算符之前断开”[3]。

遵循来自数学的传统通常会导致更易读的代码:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

在Python代码中,可以在二元运算符之前或之后断行,只要本地的惯例保持一致即可。对于新代码,建议使用Knuth的风格。
[3]: Donald Knuth的《TeXBook》,第195和196页

4
请注意,2010年的建议已更改:“可以通过将表达式括在括号中来打破长行......应优先使用括号,而不是使用反斜杠......”,并且代码示例中删除了所有反斜杠。 - e100
1
@e100:请阅读上面加粗的文本:“首选方法是使用Python括号内的隐式行连续性”,这与“将表达式包装在括号中”是相同的。我已经更新了示例。 - jfs
10
但要注意,“有时使用反斜杠会更好看”的说法也已经消失了。 - e100
7
在2015年,经过Donald Knuth的研究后,样式指南被更新以更喜欢在二元运算符之前断行,因为这样可以提高可读性。请注意,重要的是在二元运算符之前断行而不是之后。 - J2C

89

使用反斜杠来结束一行的危险在于,如果在反斜杠之后添加了空白字符(当然,这很难看到),那么反斜杠将不再执行您原本想要的操作。

请参阅 Python Idioms and Anti-Idioms (适用于Python 2Python 3) 以获取更多信息。


12
能够更好地看到行尾空格是很不错的一点;例如在vim中使用set list listchars=trail:·等类似命令。 :) - Beau
1
这不仅适用于反斜杠后面的空格。反斜杠应该严格位于行末。特别是,您不能通过在反斜杠后面断开行并在其后放置注释来注释总和中的特定术语。括号可以正常工作! :) - Roux
很遗憾这个解释在文件文档中已经消失(3.1之后)。在PEP8中,没有解释原因。 - pabouk - Ukraine stay strong

41

在您的行末添加\或将该语句括在括号( .. )中。来自IBM

b = ((i1 < 20) and
     (i2 < 30) and
     (i3 < 40))
或者
b = (i1 < 20) and \
    (i2 < 30) and \
    (i3 < 40)

30

您可以在括号和大括号之间换行。此外,您还可以在一行末尾附加反斜杠字符\以显式地换行:

x = (tuples_first_value,
     second_value)
y = 1 + \
    2

27
马上就说:显式行连接 使用反斜杠字符(\)将两个或多个物理行连接成逻辑行,如下所示:当一个物理行以非字符串文字或注释的一部分的反斜杠结尾时,它与以下行连接成为单个逻辑行,删除反斜杠和以下的换行符。例如:
if 1900 < year < 2100 and 1 <= month <= 12 \
   and 1 <= day <= 31 and 0 <= hour < 24 \
   and 0 <= minute < 60 and 0 <= second < 60:   # Looks like a valid date
        return 1

以反斜线结尾的行不能包含注释。反斜线不能延续注释。除了字符串文本(即,除字符串文本之外的标记不能使用反斜线跨越物理行拆分),反斜线不会延续标记。在字符串文本之外的行上,反斜线是非法的。


7
依据我的看法,这个例子不够地道。复合条件语句完全可以使用括号进行嵌套,这更为实用(可便于编辑或自动重排)并符合惯用说法。因此评分为-1分。 - u0b34a0f6ae

24

如果你因为一个很长的字符串而想要换行,你可以将该字符串分解成多个部分:

long_string = "a very long string"
print("a very long string")

将被替换为

long_string = (
  "a "
  "very "
  "long "
  "string"
)
print(
  "a "
  "very "
  "long "
  "string"
)

两个打印语句的输出结果:

一个很长的字符串

注意赋值语句中的括号。

还要注意,将字面字符串分成多个部分允许仅在字符串的某些部分使用字面前缀并混合分隔符:

s = (
  '''2+2='''
  f"{2+2}"
)

14

还可以将方法的调用 (obj.method()) 拆分为多行。

将命令括在括号“()”内并跨越多行:

> res = (some_object
         .apply(args)
         .filter()
         .values)

例如,我发现在链式调用Pandas/Holoviews对象方法时非常有用。


谢谢。这个方法在微软Azure课程的PySpark示例中使用。 - Roland

8

可能不是Pythonic的方式,但我通常使用带有join函数的列表来编写长字符串,例如SQL查询:

query = " ".join([
    'SELECT * FROM "TableName"',
    'WHERE "SomeColumn1"=VALUE',
    'ORDER BY "SomeColumn2"',
    'LIMIT 5;'
])

4
加入列表并非必要,而且会增加性能开销。请使用三引号字符串字面值。 - OneCricketeer
@OneCricketeer 要挑剔的话(而且在这里,挑剔似乎是一种美德),Python中的三引号应该用于文档字符串,而不是用于字符串值的换行。如果你的代码上运行了一些自动文档化的软件,它会将这个字符串字面值识别为文档字符串,所以非常不好! - undefined

4
摘自《Python旅行指南》(行连续性):
当一行逻辑代码超过规定长度时,需要将其拆分成多个物理行。如果一行的最后一个字符是反斜杠,Python解释器将连接连续的行。这在某些情况下很有用,但通常应避免使用,因为它很脆弱:在反斜杠之后添加空格会破坏代码并可能产生意想不到的结果。
更好的解决方案是在元素周围使用括号。在末尾带有未关闭括号的情况下,Python解释器将连接下一行,直到括号被关闭。大括号和中括号的行为也相同。
然而,更常见的情况是,必须拆分长的逻辑行是你试图同时完成太多事情的迹象,这可能会阻碍可读性。
话虽如此,在考虑多个导入时(超过PEP-8定义的行限制),以下是一个示例,也适用于字符串一般情况:
from app import (
    app, abort, make_response, redirect, render_template, request, session
)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接