当前位置:  开发笔记 > 编程语言 > 正文

在'if'语句中设置多行条件的样式?

如何解决《在'if'语句中设置多行条件的样式?》经验,为你挑选了9个好方法。

有时我会将ifs中的长条件分成几行.最明显的方法是:

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

视觉上不是很吸引人,因为动作与条件相融合.但是,这是使用4个空格的正确Python缩进的自然方式.

目前我正在使用:

  if (    cond1 == 'val1' and cond2 == 'val2' and
          cond3 == 'val3' and cond4 == 'val4'):
      do_something

但这不是很漂亮.:-)

你能推荐另一种方式吗?



1> Harley Holco..:

您不需要在第二个条件行上使用4个空格.也许用:

if (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

另外,不要忘记空格比您想象的更灵活:

if (   
       cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'
   ):
    do_something
if    (cond1 == 'val1' and cond2 == 'val2' and 
       cond3 == 'val3' and cond4 == 'val4'):
    do_something

但这两个都相当难看.

也许会丢失括号(虽然风格指南不鼓励这样)?

if cond1 == 'val1' and cond2 == 'val2' and \
   cond3 == 'val3' and cond4 == 'val4':
    do_something

这至少给你一些区别.

甚至:

if cond1 == 'val1' and cond2 == 'val2' and \
                       cond3 == 'val3' and \
                       cond4 == 'val4':
    do_something

我想我更喜欢:

if cond1 == 'val1' and \
   cond2 == 'val2' and \
   cond3 == 'val3' and \
   cond4 == 'val4':
    do_something

这是样式指南,(自2010年起)建议使用括号.


请注意,PEP 8不推荐使用尾随\解决方案.一个原因是,如果在编辑器中未显示空格而错误地添加空格,并且代码在语法上会变得不正确.
这是错误的,样式指南说"通过在括号中包装表达式,可以在多行中分解长行.这些应该优先使用反斜杠来表示行继续." 你可以在这里看到:http://www.python.org/dev/peps/pep-0008/#maximum-line-length
@joshcartme PEP在http://hg.python.org/peps/rev/7a48207aaab6更改为明确阻止反斜杠.我会更新答案.
谢谢,更新您的示例可能是一个好主意,因为现在不推荐它们.我试图自己解决这个问题,并且对你的答案和风格指南(因此我的评论)之间的差异感到困惑.我不仅仅是想要迂腐.
[PEP 8](https://www.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-binary-operator)现在不鼓励在`还有`和`if`。

2> S.Lott..:

我在退化的情况下使用了以下内容,它只是简单的AND或OR.

if all( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

if any( [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4'] ):

它削减了一些角色,并清楚地表明这种情况没有微妙之处.


shortcirtuiting并不总是很快.虽然不是很好的编码实践,但你可能有这样的代码:`if destroy_world and DestroyTheWorld()== world_is_destroyed:...`.太好了,现在你刚刚意外地摧毁了这个世界.你怎么能?
如果你不关心短路,那没关系.
这是一种有趣的方法.但是没有解决长期条件的问题

3> Kevin Little..:

有人必须在这里支持使用垂直空白!:)

if (     cond1 == val1
     and cond2 == val2
     and cond3 == val3
   ):
    do_stuff()

这使得每个条件都清晰可见.它还可以更清晰地表达更复杂的条件:

if (    cond1 == val1
     or 
        (     cond2_1 == val2_1
          and cond2_2 >= val2_2
          and cond2_3 != bad2_3
        )
   ):
    do_more_stuff()

是的,为了清晰起见,我们正在对一些垂直房地产进行折衷.非常值得IMO.


这似乎并不美观,也不兼容PEP8.PEP8说,打破二元运算符(例如`和`以及`或`)的首选位置是_after_运算符,而不是之前的运算符.
请不要这样做.它不仅不是"PEP8",而且更难以确定您正在链接的逻辑运算.如果它通过代码审查来到我的办公桌,我会不及格.
截至当前版本的PEP8,在二元运算符之前或之后中断[被认为是可接受的](http://legacy.python.org/dev/peps/pep-0008/#should-a-line-break-before -or-after-a-binary-operator),并且在运算符被认为更适合新代码之前.
@ChristopherMedrela是否说明了背后的理由?我认为在逻辑运算符之前放置一个换行符要清楚得多
将oprerator放在第一位在节点世界中非常普遍.理由是我们在左边注意和阅读的东西比右边的东西要快得多 - 至少在西方文化中是这样.在JavaScript中非常有效,忘记的逗号可能会导致无提示错误.
@Urda我不同意.将二元运算符放在行的开头而不是最后的IMO使得它更清楚意图是什么.在上面的第二个例子中,我认为很明显``和`的操作数在被第一个条件"或"之前被组合在一起.但也许我这么认为是因为我喜欢Lisp ......
我最喜欢这个答案,因为*禅宗的Python*`可读性很重要.`特殊情况不足以打破规则."虽然实用性超过了纯度.https://www.python.org/dev/PEPS/PEP-0020 /

4> Deestan..:

当我有一个非常大的if条件时,我更喜欢这种风格:

if (
    expr1
    and (expr2 or expr3)
    and hasattr(thingy1, '__eq__')
    or status=="HappyTimes"
):
    do_stuff()
else:
    do_other_stuff()


截至2016年:`几十年来,推荐的风格是在二元运营商之后打破.但是这会以两种方式损害可读性......"在Python代码中,只要约定在本地一致,就允许在二元运算符之前或之后中断.对于新代码,建议使用Knuth的风格.(Knuth的风格是与运营商一起开始的).
请注意,在行的开头使用`和`和`或'运算符违反[PEP 0008](https://www.python.org/dev/peps/pep-0008/),其中声明*"首选打破二元运算符的地方是在运算符之后,而不是在它之前."*.我喜欢在自己的行上使用右括号和冒号来将if条件与正文分开(并且完全可以这样做,同时将布尔运算符保持在符合PEP-0008的行的末尾).
+1用于保持缩进位置,您可以在其中跟踪它们。我喜欢python并经常使用它,但是我一直被迫如此缩进而感到烦恼。即使做得好,多线产品也确实会破坏美观。

5> krawyoti..:

这是我个人的看法:长期条件(在我看来)是一种代码气味,暗示重构为布尔返回的函数/方法.例如:

def is_action__required(...):
    return (cond1 == 'val1' and cond2 == 'val2'
            and cond3 == 'val3' and cond4 == 'val4')

现在,如果我找到一种方法使多线条件看起来很好,我可能会发现自己满足于拥有它们并跳过重构.

另一方面,让他们扰乱我的审美意识就是对重构的一种激励.

因此,我的结论是,多线条件应该看起来很丑陋,这是避免它们的动机.



6> Federico A. ..:

这并没有改善太多,但......

allCondsAreOK = (cond1 == 'val1' and cond2 == 'val2' and
                 cond3 == 'val3' and cond4 == 'val4')

if allCondsAreOK:
   do_something


布莱恩,我有点不同意.将变量用于计算的中间结果可以使代码更容易理解,并且在编译语言中不会对性能产生任何影响.它可能会在python中完成,但如果性能非常重要,我根本不会使用python.

7> DzinX..:

我建议将and关键字移动到第二行,并将包含条件的所有行缩进两个空格而不是四个:

if (cond1 == 'val1' and cond2 == 'val2'
  and cond3 == 'val3' and cond4 == 'val4'):
    do_something

这正是我在代码中解决这个问题的方法.将关键字作为行中的第一个单词使条件更具可读性,减少空格数可进一步区分条件和操作.


我在Gries或Djikstra的某个地方读过,把逻辑运算符放在行的前面 - 使得更明显 - 有帮助.自90年代以来,我一直在这样做.它有帮助.
请注意,样式指南建议将条件放在行尾.
PEP8 [不再推荐](http://legacy.python.org/dev/peps/pep-0008/#should-a-line-break-before-or-after-a-binary-operator)将条件赋予行的结尾.
这是真的,虽然我从未同意过这一点.毕竟,这只是一个指南.

8> Mark Amery..:

似乎值得引用PEP 0008(Python的官方风格指南),因为它以适度的长度评论这个问题:

if-statement 的条件部分足够长以要求它跨多行写入时,值得注意的是两个字符关键字(即if)的组合,加上一个空格,加上一个左括号创建一个自然的4-多行条件的后续行的空格缩进.这可能会与嵌套在if-statement中的缩进代码集产生视觉冲突,该代码集自然也会缩进到4个空格.该PEP没有明确地说明如何(或是否)进一步在视觉上区分这些条件线与if-statement 内的嵌套套件.在这种情况下可接受的选择包括但不限于:

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

注意上面引用中的"不限于"; 除了风格指南中提出的方法之外,在这个问题的其他答案中提出的一些方法也是可以接受的.


同样值得强调的是,PEP8明确表明其立场为**这个PEP没有明确地说明如何(或是否)进一步在视觉上区分这些条件线与if-statement内的嵌套套件.在这种情况下可接受的选择包括但不限于:...(剪断)**所以,停止争论,选择你喜欢的东西!

9> zkanda..:

这就是我所做的,记住"所有"和"任何"接受一个可迭代的,所以我只是在列表中放入一个长条件并让"all"完成工作.

condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']

if all(condition):
   do_something

推荐阅读
无名有名我无名_593
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有