有时我会把if中的长条件分解成几行。最明显的方法是:

  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

但这不是很漂亮

你能推荐另一种方法吗?


当前回答

  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

在这种情况下,缩进不应该是4的倍数,例如,请参见“与开头分隔符对齐”:

http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation

其他回答

我认为@zkanda的解决方案稍加改动会很好。如果您在各自的列表中列出了条件和值,则可以使用列表理解来进行比较,这将使添加条件/值对的情况更加普遍。

conditions = [1, 2, 3, 4]
values = [1, 2, 3, 4]
if all([c==v for c, v in zip(conditions, values)]):
    # do something

如果我真的想对这样的语句进行硬编码,为了易读,我会这样写:

if (condition1==value1) and (condition2==value2) and \
   (condition3==value3) and (condition4==value4):

只需要用iand运算符抛出另一个解决方案:

proceed = True
for c, v in zip(conditions, values):
    proceed &= c==v

if proceed:
    # do something

在退化情况下,我采用了以下方法,即简单的AND或or。

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

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

它剃掉了几个字符,并清楚地表明没有任何微妙的条件。

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

如果if语句的条件部分足够长,需要跨多行编写,那么值得注意的是,两个字符的关键字(即if)加上一个空格和一个左括号的组合会为多行条件语句的后续行创建一个自然的4空格缩进。这可能会与嵌套在if语句中的缩进代码集产生视觉冲突,这也会自然缩进到4个空格。对于如何(或是否)进一步从视觉上区分if语句中的嵌套套件和这些条件行,PEP没有明确的立场。这种情况下可接受的选项包括但不限于:#无额外压痕。如果(this_is_one_thing和that_is_aother_thing):do_something()#添加注释,这将在编辑器中提供一些区别#支持语法高亮显示。如果(this_is_one_thing和that_is_aother_thing):#既然这两个条件都成立,我们就可以结婚了。do_something()#在条件延续行上添加一些额外的缩进。如果(this_is_one_thing和that_is_aother_thing):do_something()

请注意上述报价中的“不限于”;除了风格指南中建议的方法外,其他问题答案中建议的一些方法也是可以接受的。

我通常做的是:

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

这样,右括号和冒号可视地标志着我们的状态结束。

我也一直在努力找到一种体面的方式来做这件事,所以我只是想出了一个主意(不是银弹,因为这主要是品味问题)。

if bool(condition1 and
        condition2 and
        ...
        conditionN):
    foo()
    bar()

与我见过的其他解决方案相比,我发现这个解决方案有一些优点,即,您可以获得额外的4个缩进空间(bool),允许所有条件垂直排列,并且if语句的主体可以以清晰的方式缩进。这也保留了布尔运算符短路求值的优点,但当然增加了基本上什么都不做的函数调用的开销。您可以(有效地)辩称,任何返回其参数的函数都可以在这里使用,而不是bool,但正如我所说,这只是一个想法,最终还是一个口味问题。

有趣的是,当我写这篇文章并思考“问题”时,我想到了另一个想法,它消除了函数调用的开销。为什么不使用额外的括号对来表示我们将要进入一个复杂的条件呢?再多说2个,以相对于if语句的主体对子条件进行2个空格的缩进。例子:

if (((foo and
      bar and
      frob and
      ninja_bear))):
    do_stuff()

我有点喜欢这样,因为当你看着它时,一个铃声立刻在你的脑海中响起:“嘿,这里发生了一件复杂的事情!”。是的,我知道括号对可读性没有帮助,但这些条件应该很少出现,当它们出现时,你必须停下来仔细阅读它们(因为它们很复杂)。

总之,还有两个我没有看到的提案。希望这对某人有所帮助:)