在“if”语句中设置多行条件的样式?[已结束]

Styling multi-line conditions in 'if' statements? [closed]

提问人:Eli Bendersky 提问时间:10/8/2008 最后编辑:General GrievanceEli Bendersky 更新时间:5/16/2023 访问量:1593648

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章来用事实和引文来回答。

3年前关闭。

社区去年审查了是否重新讨论这个问题,并关闭了它:

原始关闭原因未解决

有时我会将 s 中的长条件分解为几行。最明显的方法是: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

但这并不是很漂亮。:-)

您能推荐另一种方式吗?

python if 语句

评论

2赞 akaihola 10/22/2013
如果您的编辑器使用 pep8 Python 包来检测何时警告 PEP8 违规,则必须禁用 E125 错误或找到满足包条件的格式化解决方案。软件包的问题 #126 是关于修复软件包以严格遵循 PEP8 规范。该问题的讨论包括一些风格建议,也可以在此处查看。pep8pep8
1赞 Taylor D. Edmiston 9/7/2016
请注意,对于第一个示例,pep8 将抛出“E129 视觉缩进行,缩进与下一个逻辑行相同”。

答:

30赞 Federico A. Ramponi 10/8/2008 #1

这并没有太大的改善,但是......

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

if allCondsAreOK:
   do_something

评论

1赞 Eli Bendersky 10/8/2008
有趣的选择。但是2行额外的:-)
11赞 Mark Baker 10/8/2008
布莱恩,我部分不同意。将变量用于计算的中间结果可以使代码更易于理解,并且在编译语言中不会对性能产生任何影响。它可能会在 python 中完成,但如果性能如此重要,我根本不会使用 python。
2赞 Jonathan Hartley 10/9/2012
@MarkBaker 我曾经同意你写的东西,直到我读了马丁·福勒斯(Martin Fowlers)的《重构》。他提供了一个很好的论点,即这种中间变量弊大于利。它们会抑制后续的重构。没有它们会导致一种更实用的编程风格,这非常适合重构。这让我很惊讶,但我相信他是对的,并且从那以后一直在努力从我的代码中消除像这样不必要的中间体——即使它们被多次使用。
1赞 Jonathan Hartley 10/9/2012
此外,我将借此机会声明,使用缓慢的编程语言(例如 Python)不会导致应用程序性能问题。自从我从 C++ 和 C# 切换到 Python 以来的六年里,我没有发现我的代码再遇到任何性能问题。当它出现时,这被证明是由于错误的算法选择或 IO。在那段时间里,我只发现 Python 性能在任何重要方面都有所欠缺——在将顶点发送到 OpenGL 之前,每一帧都会变形顶点网格。在这种情况下,正确且明显的解决方案(使用Numpy或着色器)修复了它。
3赞 Leonid Shvechikov 3/18/2013
很好,但为什么是骆驼?!:)
976赞 Harley Holcombe 10/8/2008 #2

您不需要在第二个条件行上使用 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 年以来)建议使用括号。

评论

66赞 Eric O. Lebigot 1/14/2011
请注意,PEP 8 不推荐尾随 \ 解决方案。一个原因是,如果在 \ 之后错误地添加了空格,它可能不会显示在编辑器中,并且代码在语法上变得不正确。
26赞 joshcartme 1/22/2013
这是错误的,风格指南说“ 长行可以通过将表达式括在括号中来分隔在多行上。这些应优先使用,而不是使用反斜杠作为行延续。你可以在这里看到这个:python.org/dev/peps/pep-0008/#maximum-line-length
11赞 Harley Holcombe 1/22/2013
@joshcartme PEP 在 hg.python.org/peps/rev/7a48207aaab6 年进行了更改,以明确阻止反斜杠。我会更新答案。
4赞 joshcartme 1/23/2013
谢谢,更新您的示例也可能是个好主意,因为现在不推荐使用它们。我试图自己弄清楚这一点,并对您的答案和风格指南之间的差异感到困惑(因此我的评论)。我不只是想变得迂腐。
11赞 virtualxtc 9/11/2018
PEP 8 现在也不鼓励在 and 之后中断。andif
19赞 Dzinx 10/8/2008 #3

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

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

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

评论

10赞 S.Lott 10/8/2008
我在 Gries 或 Djikstra 的某个地方读到,将逻辑运算符放在行的前面——让更明显——有帮助。我从90年代就开始这样做了。它有帮助。
7赞 Harley Holcombe 10/10/2008
请注意,样式指南建议将条件放在行的末尾。
3赞 Dzinx 10/10/2008
这是真的,尽管我从未同意这一点。毕竟,这只是一个指南。
10赞 Soren Bjornstad 11/11/2016
PEP8 不再建议将条件放在行尾。
75赞 Deestan 10/8/2008 #4

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

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

评论

7赞 mightypile 12/23/2013
+1 用于将缩进保留在您可以跟踪它们的位置。我喜欢 python 并经常使用它,但我总是因为被迫缩进而感到恼火。多线如果真的破坏了美感,即使做得好。
6赞 Mark Amery 7/5/2015
请注意,将 ur 和 运算符放在行的开头违反了 PEP 0008,该条指出“绕过二进制运算符的首选位置是在运算符之后,而不是在运算符之前。不过,我喜欢将右括号和冒号放在它们自己的行上,以将 if 条件与正文分开(并且完全可以这样做,同时将您的布尔运算符保持在行的末尾以符合 PEP-0008 的要求)。andor
32赞 cowbert 1/12/2018
截至 2016 年:...(Knuth 的风格是用运算符开始行)。For decades the recommended style was to break after binary operators. But this can hurt readability in two waysIn Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested.
146赞 S.Lott 10/8/2008 #5

在退化的情况下,我采用了以下方法,它只是 AND 或 OR。

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

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

它剃掉了几个字符,并清楚地表明这种情况没有微妙之处。

评论

6赞 Eli Bendersky 10/8/2008
这是一种有趣的方法。不过,它并不能解决长期条件的问题
26赞 Constantin 10/10/2008
如果你不在乎短路也没关系。
71赞 Aaron 1/29/2009
缩短并不总是关于快速。虽然不是很好的编码实践,但您可能有这样的现有代码: .太好了,现在你只是意外地摧毁了世界。你怎么能?if destroy_world and DestroyTheWorld() == world_is_destroyed: ...
13赞 Przemek D 5/29/2018
我很惊讶这有这么多的赞成票。这个答案完全忽略了关于设置多行条件样式的原始问题。
2赞 eugene-bright 8/6/2018
这个表达不是懒惰的。因此,如果遵循某些保护条件,则可能失败,这并不等同。
3赞 Anders Waldenborg 10/8/2008 #6

“all”和“any”对于同一类型情况的许多条件都很好。但是他们总是评估所有条件。如本示例所示:

def c1():
    print " Executed c1"
    return False
def c2():
    print " Executed c2"
    return False


print "simple and (aborts early!)"
if c1() and c2():
    pass

print

print "all (executes all :( )"
if all((c1(),c2())):
    pass

print

评论

5赞 habnabit 1/27/2009
不對!他们这样做只是因为你这样做。尝试 all(f() for f in [c1, c2])。
2赞 Brandon Rhodes 1/16/2011
我认为他只是以函数为例,因为他可以很容易地让它们打印一些东西。如果我们考虑在列表中提供的一系列任意表达式,除非您打算将它们每个都包装在 lambda 中使用您的技巧,否则它们都将被计算。换句话说,Aaron:我认为 Anders 试图以可调用对象为具体例子来谈论一般条件;但您的反驳仅适用于函数。all()f()
67赞 Kevin Little 10/8/2008 #7

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

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。

评论

22赞 Chris Medrela 10/26/2013
这似乎既不漂亮,也不兼容 PEP8。PEP8 表示,围绕二进制运算符(例如和 )中断的首选位置是在运算符之后,而不是在运算符之前。andor
12赞 Norill Tempest 5/9/2014
它@ChristopherMedrela说明这背后的原理?我认为在逻辑运算符之前放置换行符要清楚得多
11赞 Urda 3/5/2015
请不要这样做。它不仅不是,而且使确定您正在链接的逻辑操作变得更加困难。如果它通过代码审查来到我的办公桌上,我会失败。PEP8
7赞 jamesdlin 8/13/2015
@Urda 我不同意。将二进制运算符放在行的开头而不是 IMO 的末尾可以更清楚地说明意图是什么。在上面的第二个例子中,我认为很明显,在遇到第一个条件之前,操作数 to 被组合在一起。但也许我之所以这么认为,是因为我喜欢 Lisp......andor
15赞 Soren Bjornstad 11/11/2016
从当前版本的 PEP8 开始,在二进制运算符之前或之后中断被认为是可以接受的,并且在运算符被认为更适合新代码之前。
1赞 Jason Baker 10/9/2008 #8

为了完整起见,只是其他一些随机的想法。如果它们对您有用,请使用它们。否则,你最好尝试别的东西。

您也可以使用字典来执行此操作:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

此选项更复杂,但您可能还会发现它很有用:

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

不知道这是否适合您,但这是另一种可以考虑的选择。这是另一种方法:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

最后两个我还没有测试过,但如果这是你想要的,这些概念应该足以让你继续前进。

(郑重声明,如果这只是一次性的事情,那么最好使用您最初提出的方法。如果你在很多地方进行比较,这些方法可能会提高可读性,让你不会因为它们有点笨拙而感到难过。

2赞 Federico A. Ramponi 10/9/2008 #9

如果我们只在条件和正文之间插入一个额外的空行,然后以规范的方式执行其余的操作,该怎么办?

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

    do_something

p.s. 我总是使用制表符,而不是空格;我无法微调...

评论

3赞 Eli Bendersky 10/9/2008
我认为这会非常令人困惑,尤其是当条件的主体很长时。
0赞 virtualxtc 9/11/2018
我同意 Eli 的观点,这里的封装和缩进对于长行来说是令人困惑的。此外,新规则是 and 语句应从下一行开始andor
0赞 psihodelia 6/9/2010 #10

将您的条件打包到一个列表中,然后执行 smth。喜欢:

if False not in Conditions:
    do_something
4赞 Fred Nurk 1/14/2011 #11

(我略微修改了标识符,因为固定宽度的名称不能代表真实代码 - 至少不是我遇到的真实代码 - 并且会掩盖示例的可读性。

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4"):
    do_something

这适用于“and”和“or”(重要的是它们在第二行的第一行),但对于其他长条件则不那么有效。幸运的是,前者似乎是更常见的情况,而后者通常很容易用临时变量重写。(这通常并不难,但在重写时保留“and”/“or”的短路可能很困难或不太明显/可读。

由于我从您关于 C++ 的博客文章中发现了这个问题,因此我将包括我的 C++ 风格是相同的:

if (cond1 == "val1" and cond22 == "val2"
and cond333 == "val3" and cond4444 == "val4") {
    do_something
}
28赞 krawyoti 1/14/2011 #12

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

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

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

另一方面,让它们扰乱我的审美意识会成为重构的动力。

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

4赞 Marius Gedminas 1/14/2011 #13

我很惊讶没有看到我的首选解决方案,

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

由于是一个关键字,因此我的编辑器会突出显示它,并且看起来与它下面的do_something完全不同。and

评论

1赞 Chris Medrela 10/26/2013
但是延续行仍然没有将自己与下一个逻辑行区分开来......
1赞 Mark Amery 7/5/2015
请注意,这是 PEP 0008 违规(“绕过二进制运算符的首选位置是在运算符之后,而不是在运算符之前”)。当然,你是否在乎,取决于你。
2赞 Marius Gedminas 7/13/2015
顺便说一句,这不再是我的首选解决方案。;)
5赞 Apalala 1/20/2011 #14

补充@krawyoti说的......长时间的条件闻起来是因为它们难以阅读和理解。使用函数或变量可使代码更清晰。在 Python 中,我更喜欢使用垂直空格,用括号括起来,并将逻辑运算符放在每行的开头,这样表达式就不会看起来像“浮动”。

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

如果需要多次评估条件,例如在循环中,则最好使用局部函数。while

评论

1赞 Techdragon 5/5/2013
除此之外,您还可以声明一个函数或 lambda 来返回您的 true、false,而不是创建一个额外的变量。
0赞 Sri Kadimisetty 9/1/2013
@Techdragon如果条件位于其他位置,则将它们放入 lambda 块中将需要命名 lambda 块,以便稍后可以在 if 条件中引用它。如果要命名 lambda,为什么它毕竟不是常规函数?我个人喜欢这种简化的布尔表达式。
0赞 Techdragon 9/13/2013
我同意,这就是为什么在大多数情况下,我通常会使用一个函数来提高可读性和在略读理解程序控制流时易于心理消化。我提到 lambda 是为了确保在人们特别注重空间的情况下也存在“较小”选项。
0赞 howdoicode 9/30/2020
这很酷。不幸的是,如果我在变量子句中包含或包含,我会收到 .Path(input).is_dir()Path(input).is_file()TypeError: 'bool' object is not callable
0赞 xorsyst 9/22/2011 #15

我发现,当我有长条件时,我经常有一个短代码正文。在这种情况下,我只是对正文进行双缩进,因此:

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

评论

1赞 xorsyst 3/13/2012
@qarma,你愿意扩张吗?这肯定比使用 PEP 8 建议不要使用的行延续字符要好
0赞 Dima Tisnek 3/14/2012
这实际上是行延续的有效案例。IMPO 括号表示元组或函数调用。OP 的使用非常像 C,我尽可能更喜欢 python 语法。不过,我承认 \ 并没有受到普遍青睐。
0赞 Dima Tisnek 3/13/2012 #16
  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

评论

0赞 Anton Strogonoff 4/8/2012
谷歌的指南还提供了一个复杂条件的例子,它与OP提到的“最明显的方法”相匹配。尽管该指南没有明确提倡以这种方式格式化长“如果”。
6赞 rgenito 3/7/2013 #17

就我个人而言,我喜欢为长 if 语句添加含义。我必须搜索代码才能找到一个合适的示例,但这是我想到的第一个示例:假设我碰巧遇到了一些古怪的逻辑,我想根据许多变量显示某个页面。

中文(简体) : “如果登录用户不是管理员教师,而只是普通教师,并且本身不是学生......”

if not user.isAdmin() and user.isTeacher() and not user.isStudent():
    doSomething()

当然,这可能看起来不错,但是阅读这些 if 语句需要做很多工作。我们把逻辑分配给有意义的标签怎么样。“label”实际上是变量名称:

displayTeacherPanel = not user.isAdmin() and user.isTeacher() and not user.isStudent()
if displayTeacherPanel:
    showTeacherPanel()

这可能看起来很傻,但您可能还有另一种情况,即您只想显示另一个项目,当且仅当您显示教师面板或用户默认有权访问该其他特定面板时:

if displayTeacherPanel or user.canSeeSpecialPanel():
    showSpecialPanel()

尝试在不使用变量来存储和标记逻辑的情况下编写上述条件,不仅最终会得到一个非常混乱、难以阅读的逻辑语句,而且您也只是重复了自己。虽然有合理的例外,但请记住:不要重复自己 (DRY)。

2赞 tomekwi 8/2/2014 #18

我通常做的是:

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

这样,闭合支架和冒号在视觉上标志着我们病情的结束。

评论

1赞 virtualxtc 9/11/2018
几乎正确;PEP 8 现在建议在 or 之前断开。andor
0赞 user1487551 10/17/2014 #19

这是另一种方法:

cond_list = ['cond1 == "val1"','cond2=="val2"','cond3=="val3"','cond4=="val4"']
if all([eval(i) for i in cond_list]):
 do something

这也使得只需将另一个条件附加到列表中即可轻松添加另一个条件,而无需更改 if 语句:

cond_list.append('cond5=="val5"')
8赞 zkanda 11/19/2014 #20

这是我所做的,请记住“all”和“any”接受可迭代对象,所以我只是在列表中放了一个长条件,让“all”完成工作。

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

if all(condition):
   do_something

评论

1赞 Oleg 3/4/2021
如果要检查函数,或者是 的属性,则情况不好。示例条件:cond4cond2cond1object is not None and object.param == 5 and object.is_running()
0赞 kdb 5/31/2021
在这一点上,为什么不只是?更清晰(没有逻辑运算符和条件的分离)并保留短路行为。condition = cond1 == 'val1' and cond2 == 'val2' ...
5赞 ThorSummoner 11/24/2014 #21

简单明了,也通过了 pep8 检查:

if (
    cond1 and
    cond2
):
    print("Hello World!")

最近,我一直更喜欢 and 函数,因为我很少混合 And 和 Or 比较,这效果很好,并且具有与生成器理解一起提前失败的额外优势:allany

if all([
    cond1,
    cond2,
]):
    print("Hello World!")

只要记住传入一个可迭代对象!传入 N 个参数是不正确的。

注意:就像很多比较,就像很多比较。anyoralland


这与生成器推导很好地结合在一起,例如:

# Check if every string in a list contains a substring:
my_list = [
    'a substring is like a string', 
    'another substring'
]

if all('substring' in item for item in my_list):
   print("Hello World!")

# or

if all(
    'substring' in item
    for item in my_list
):
    print("Hello World!")

More on: generator comprehension

评论

1赞 ThorSummoner 12/3/2016
I should also point out that pylint's stock configuration wants an entra indent on line continuation in an if; which has dissuaded me from using this scheme.
1赞 El Ninja Trepador 12/4/2014 #22

I've been struggling to find a decent way to do this as well, so I just came up with an idea (not a silver bullet, since this is mainly a matter of taste).

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

I find a few merits in this solution compared to others I've seen, namely, you get exactly an extra 4 spaces of indentation (bool), allowing all conditions to line up vertically, and the body of the if statement can be indented in a clear(ish) way. This also keeps the benefits of short-circuit evaluation of boolean operators, but of course adds the overhead of a function call that basically does nothing. You could argue (validly) that any function returning its argument could be used here instead of bool, but like I said, it's just an idea and it's ultimately a matter of taste.

Funny enough, as I was writing this and thinking about the "problem", I came up with yet another idea, which removes the overhead of a function call. Why not indicate that we're about to enter a complex condition by using extra pairs of parentheses? Say, 2 more, to give a nice 2 space indent of the sub-conditions relative to the body of the if statement. Example:

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

I kind of like this because when you look at it, a bell immediatelly rings in your head saying "hey, there's a complex thing going on here!". Yes, I know that parentheses don't help readability, but these conditions should appear rarely enough, and when they do show up, you are going to have to stop and read them carefuly anyway (because they're complex).

Anyway, just two more proposals that I haven't seen here. Hope this helps someone :)

0赞 Artur Gaspar 3/5/2015 #23

I usually use:

if ((cond1 == 'val1' and cond2 == 'val2' and
     cond3 == 'val3' and cond4 == 'val4')):
    do_something()
18赞 Mark Amery 7/5/2015 #24

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

当 -statement 的条件部分足够长,需要跨多行编写时,值得注意的是,两个字符关键字的组合(即 ),加上一个空格,加上一个左括号,为多行条件的后续行创建一个自然的 4 空格缩进。这可能会与嵌套在 -语句中的缩进代码套件产生视觉冲突,该代码套件自然也会缩进到 4 个空格。对于如何(或是否)进一步直观地将此类条件行与 -语句中的嵌套套件区分开来,此 PEP 没有明确的立场。在这种情况下,可接受的选项包括但不限于:ifififif

# 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()

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

评论

0赞 Michael 6/14/2016
PEP8 为 +1。这应该被接受,因为它(实际上)是官方的 Python 风格指南。
3赞 RayLuo 9/14/2016
同样值得强调的是,PEP8 明确表明了它的立场,因为 这个 PEP 对如何(或是否)进一步直观地将此类条件行与 if 语句中的嵌套套件区分开来没有明确的立场。在这种情况下,可接受的选项包括但不限于:......(截断)所以,别吵了,去你喜欢的东西吧!
0赞 Gautam 12/6/2015 #25

如果我们的 if & an else 条件必须在其中执行多个语句,那么我们可以像下面这样写。 每当我们有 if else 示例时,其中包含一个语句。

谢谢它为我工作。

#!/usr/bin/python
import sys
numberOfArgument =len(sys.argv)
weblogic_username =''
weblogic_password = ''
weblogic_admin_server_host =''
weblogic_admin_server_port =''


if numberOfArgument == 5:
        weblogic_username = sys.argv[1]
        weblogic_password = sys.argv[2]
        weblogic_admin_server_host =sys.argv[3]
        weblogic_admin_server_port=sys.argv[4]
elif numberOfArgument <5:
        print " weblogic UserName, weblogic Password and weblogic host details are Mandatory like, defalutUser, passwordForDefaultUser, t3s://server.domainname:7001 ."
        weblogic_username = raw_input("Enter Weblogic user Name")
        weblogic_password = raw_input('Enter Weblogic user Password')
        weblogic_admin_server_host = raw_input('Enter Weblogic admin host ')
        weblogic_admin_server_port = raw_input('Enter Weblogic admin port')
#enfelif
#endIf
1赞 SarcasticSully 8/5/2016 #26

你可以把它分成两行

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

甚至一次添加一个条件。这样,至少它将杂乱无章与.if

2赞 SMGreenfield 11/30/2016 #27

我知道这个线程很旧,但我有一些 Python 2.7 代码,而 PyCharm (4.5) 仍然抱怨这种情况:

if foo is not None:
    if (cond1 == 'val1' and cond2 == 'val2' and
        cond3 == 'val3' and cond4 == 'val4'):
            # some comment about do_something
            do_something

即使有 PEP8 警告“视觉上缩进的行与下一个逻辑行的缩进相同”,实际代码是完全可以的吗?这不是“过度缩进”吗?

...有时我希望 Python 能咬紧牙关,只用大括号。我想知道这些年来有多少错误是由于意外的错误缩进而意外引入的......

评论

0赞 Kasir Barati 6/28/2022
这是一个糟糕的设计AFAIK。我的意思是,如果我们必须进行这种编码,我们应该重新考虑我们的代码。TBH,我有同样的问题。我来自Node.js背景,在那个维度上我们不关心这个问题,直接来说,这根本不是问题。在 node.js 中,我们有更漂亮的。顺便说一句,我想在这种情况下,如果我们有教条主义的信念,我们应该改变我们的教条主义信念。
2赞 Stof 6/17/2017 #28

所有还为 if 语句提供多条件的受访者都与所提出的问题一样丑陋。你不会通过做同样的事情来解决这个问题。

即使是 PEP 0008 的答案也是令人厌恶的。

这是一种更具可读性的方法

condition = random.randint(0, 100) # to demonstrate
anti_conditions = [42, 67, 12]
if condition not in anti_conditions:
    pass

想让我吃掉我的话吗?说服我你需要多条件,我会从字面上打印出来并吃掉它供你娱乐。

评论

0赞 saul 3/7/2018
这确实是一种非常巧妙的多条件:)不知道为什么:)没有更多的选票,有什么注意事项吗?
0赞 Stof 3/12/2018
@SaulCruz真的没有 不仅条件变量不需要重复,您还可以节省检查每个值的许多重复次数,这只是将值放在一个数组中,让引擎为您检查条件
1赞 Jeyekomon 6/6/2018
@Stoff 感谢您删除我的评论。我想指出的是,你的方法没有回答OP的问题。您提供的代码不能应用于问题中的代码。如果你不这么认为,那么你应该添加OP的代码,通过你的方法重新格式化,以证明你的观点。
0赞 Stof 6/6/2018
这不是公认的答案,但它显然是一种替代方法(其他人同意)。SO 鼓励其他答案,那么论点到底是什么?明确你自己的问题,如果你需要适当的关注,也许可以考虑提出你自己的问题。P.s. 我不是 SO mod,我无法删除评论
3赞 ryanjdillon 7/21/2017 #29

我认为@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 I did want to hard-code a statement like this, I would write it like this for legibility:

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

And just to throw another solution out there with an iand operator:

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

if proceed:
    # do something

评论

2赞 Gabriel Garcia 9/6/2017
Just for fun: . (with all(map(eq, have, expected))from operator import eq)
1赞 Nader Belal 10/26/2019 #30

Pardon my noobness, but it happens that I'm not as knowledgeable of #Python as anyone of you here, but it happens that I have found something similar when scripting my own objects in a 3D BIM modeling, so I will adapt my algorithm to that of python.

The problem that I find here, is double sided:

  1. Values my seem foreign for someone who may try to decipher the script.
  2. Code maintenance will come at a high cost, if those values are changed (most probable), or if new conditions must be added (broken schema)

Do to bypass all these problems, your script must go like this

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed


if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

Pros of this method:

  1. Script is readable.

  2. Script can be easy maintained.

  3. conditions is a 1 comparison operation to a sum of values that represents the desired conditions.
  4. No need for multilevel conditions

Hope it help you all