Python中链式调用时换行的正确风格
我有一些代码,想问一下,break应该放在句号前面还是后面呢?
# before
my_var = somethinglikethis.where(we=do_things).where(we=domore).where(we=everdomore)
# this way
my_var = somethinglikethis.where(we=do_things) \
.where(we=domore) \
.where(we=everdomore)
# or this way
my_var = somethinglikethis.where(we=do_things). \
where(we=domore). \
where(we=everdomore)
3 个回答
做有效的事情。
另外,看看这篇关于Python中缩进神话的白皮书。你可以在这里找到它。
它开头提到:
“在Python源代码中,空白是有意义的。”
其实,不是所有的空白都有意义。只有你代码的缩进级别是重要的(也就是你代码最左边的空白)。在其他地方,空白就不重要了,可以随意使用,就像在其他编程语言中一样。你也可以在任何地方插入空行,这些空行可以什么都不包含(或者只包含一些随意的空白)。
希望这能帮到你。
顺便说一下,autopep8(加上一个 --aggressive
的选项)把你的原始代码变成了这个:
my_var = somethinglikethis.where(
we=do_things).where(
we=domore).where(
we=everdomore)
不过我同意,Bastien 的解决方案更优雅。
PEP 8建议使用括号,这样就不需要用\
来换行了,并且温和地建议在二元运算符之前换行,而不是之后。因此,格式化代码的推荐方式是这样的:
my_var = (somethinglikethis
.where(we=do_things)
.where(we=domore)
.where(we=everdomore))
相关的两段内容来自于最大行长度部分:
换行的推荐方式是使用Python在括号、方括号和大括号内的隐式换行。长行可以通过在括号内包裹表达式来分成多行。这种方式比使用反斜杠换行更受欢迎。
... 还有整个在二元运算符之前还是之后换行?部分:
在二元运算符之前还是之后换行?
几十年来,推荐的风格是换行在二元运算符之后。但这样会影响可读性,主要有两个原因:运算符会分散到屏幕的不同列上,每个运算符也会离开它的操作数,移动到上一行。在这种情况下,眼睛需要额外努力去判断哪些是加法,哪些是减法:
# No: operators sit far away from their operands income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
为了解决这个可读性问题,数学家和他们的出版商遵循了相反的惯例。唐纳德·克努斯在他的计算机与排版系列中解释了传统规则:“虽然段落中的公式总是在二元运算和关系之后换行,但展示的公式总是在二元运算之前换行。”
遵循数学的传统通常会导致代码更易读:
# Yes: easy to match operators with operands income = (gross_wages + taxable_interest + (dividends - qualified_dividends) - ira_deduction - student_loan_interest)
在Python代码中,可以在二元运算符之前或之后换行,只要在局部保持一致即可。对于新代码,建议使用克努斯的风格。
需要注意的是,正如上面引用的内容所示,PEP 8曾经给出了相反的建议,关于在运算符周围换行的位置,以下是引用的内容以供后人参考:
换行的推荐方式是使用Python在括号、方括号和大括号内的隐式换行。长行可以通过在括号内包裹表达式来分成多行。这种方式比使用反斜杠换行更受欢迎。确保适当地缩进继续的行。推荐在二元运算符周围换行的位置是在运算符之后,而不是之前。一些例子:
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)