ChatGPT解决这个技术问题 Extra ChatGPT

在“if”语句中设置多行条件的样式? [关闭]

关闭。这个问题是基于意见的。它目前不接受答案。想改进这个问题?更新问题,以便可以通过编辑这篇文章用事实和引用来回答它。 2年前关闭。改进这个问题

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

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

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

目前我正在使用:

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

但这不是很漂亮。 :-)

你能推荐一种替代方法吗?

如果您的编辑器使用 pep8 Python 包来检测何时对 PEP8 违规发出警告,则您必须禁用 E125 错误或找到满足 pep8 包标准的格式化解决方案。 pep8 包的 issue #126 是关于修复包以严格遵循 PEP8 规范。对这个问题的讨论包括一些在这里也能看到的风格建议。
请注意,对于第一个示例,pep8 将抛出“E129 视觉缩进行,缩进与下一个逻辑行相同”。
这个问题非常古老并且有很多观点,但它明确地基于观点。语言“不是很吸引人”和“不是很漂亮”列出了所谓的正确答案是最符合提问者审美偏好(即意见)的标准。我可以问完全相同的问题并声称它不是重复的,因为我的审美品味将其定性为不同,并且会导致不同的“正确”答案。
@Z4-tier:是的,它是基于意见的。但它是在 12 年前被问到的。那时,SO 是一个不同的、更友善的地方。由于 SO 的标准发生了变化,最近它一直在积累反对票。尽管如此,已经被观看了超过 100 万次,我希望它在世界上的好处多于坏处。我当然可以看到人们今天想知道同样的问题,谷歌搜索它,登陆这个讨论并发现它对校准他们的想法很有用。有几个高度投票的答案可供选择。
@EliBendersky 完全同意。就像 SO 有一个持续的身份危机:虽然它显然不符合“规则”(有效答案的数量证明了这一点),但很明显它增加了价值。在所有条件相同的情况下,我宁愿与对编码风格形成清晰合理的观点的人合作,即使他们的观点与我的不同。

m
mardlin

您不需要在第二个条件行上使用 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

不过,这两个都相当丑陋。

也许会丢失括号(但 Style Guide 不鼓励这样做)?

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

这是 Style Guide,它(自 2010 年以来)建议使用方括号。


请注意,PEP 8 不建议使用尾随 \ 解决方案。一个原因是,如果在 \ 之后错误地添加了一个空格,它可能不会显示在您的编辑器中,并且代码在语法上变得不正确。
这是错误的,样式指南说“可以通过将表达式括在括号中来将长行拆分为多行。应该优先使用这些行,而不是使用反斜杠来续行。”您可以在此处看到:python.org/dev/peps/pep-0008/#maximum-line-length
@joshcartme PEP 在 hg.python.org/peps/rev/7a48207aaab6 处更改以明确禁止使用反斜杠。我会更新答案。
谢谢,更新您的示例可能也是一个好主意,因为现在不推荐使用它们。我试图自己弄清楚这一点,并且对您的答案与风格指南之间的差异感到困惑(因此我发表了评论)。我不只是想学究气。
PEP 8 现在也不鼓励在 andif 之后中断。
S
S.Lott

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

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

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

它刮掉了一些字符,并清楚地表明这种情况没有微妙之处。


这是一个有趣的方法。虽然没有解决长条件的问题
如果你不关心短路也没关系。
短路并不总是很快。虽然不是良好的编码习惯,但您可能有这样的现有代码:if destroy_world and DestroyTheWorld() == world_is_destroyed: ...。太好了,现在你只是意外摧毁了世界。你怎么能?
我很惊讶这有这么多的赞成票。这个答案完全忽略了关于样式化多行条件的原始问题。
这种表达方式并不懒惰。因此,如果某些保护条件可能会失败,则它是不等价的。
K
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()

是的,为了清晰起见,我们正在权衡一些垂直空间。海事组织非常值得。


这似乎既不美观也不兼容 PEP8。 PEP8 表示,绕过二元运算符(例如 andor)的首选位置是在运算符之后,而不是在它之前。
@ChristopherMedrela 它是否说明了其背后的基本原理?我认为在逻辑运算符之前放置一个换行符会更清晰
请不要这样做。它不仅不是 PEP8,而且更难确定您链接的逻辑操作。如果它通过代码审查出现在我的办公桌上,我会不及格。
@Urda 我不同意。将二元运算符放在行的开头而不是结尾 IMO 可以更清楚地说明意图是什么。在上面的第二个示例中,我认为很明显 and 的操作数在被第一个条件 or 之前组合在一起。但也许我这么认为是因为我喜欢 Lisp……
从当前版本的 PEP8 开始,在二元运算符 is considered acceptable 之前或之后中断,并且在运算符被认为更适合新代码之前中断。
g
gitaarik

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

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

+1 用于在可以跟踪它们的地方保留缩进。我喜欢 python 并且经常使用它,但我经常因为被迫缩进而感到恼火。即使做得好,多线如果真的破坏了美感。
请注意,将 andor 运算符放在行首违反了 PEP 0008,其中指出 “绕过二元运算符的首选位置是在运算符之后,而不是在它之前。”。不过,我喜欢将右括号和冒号放在自己的行上,以将 if 条件与正文分开(并且完全有可能做到这一点,同时将布尔运算符保持在行尾以符合 PEP-0008)。
截至 2016 年:For decades the recommended style was to break after binary operators. But this can hurt readability in two ways...In 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.(Knuth 的风格是以运算符开头)。
F
Federico A. Ramponi

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

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

if allCondsAreOK:
   do_something

有趣的选择。但是额外的 2 行:-)
布赖恩,我部分不同意。将变量用于计算的中间结果可以使代码更容易理解,并且在编译语言中不会对性能产生任何影响。它可能会在 python 中完成,但如果性能如此重要,我根本不会使用 python。
@MarkBaker我曾经同意你写的东西,直到我读到Martin Fowlers“重构”。他提供了一个极好的论点,即此类中间变量弊大于利。它们抑制了后续的重构。没有它们会导致更函数化的编程风格,这很适合重构。这让我感到惊讶,但我相信他是对的,并且从那以后一直努力从我的代码中消除像这样的不必要的中间体——即使它们被多次使用。
另外,我将借此机会声明使用慢速编程语言(例如 Python)不会导致应用程序性能问题。自从我从 C++ 和 C# 切换到 Python 以来的六年里,我没有发现我的代码遇到任何性能问题。当它发生时,这原来是由于错误的算法选择或 IO 造成的。在那段时间里,我只有一次发现 Python 的性能在任何重要的方面都缺乏 - 在将顶点网格发送到 OpenGL 之前,每帧都变形顶点网格。在这种情况下,正确且明显的解决方案(使用 Numpy 或着色器)修复了它。
很好,但为什么是骆驼案?! :)
L
Luke H

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

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

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

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

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


D
DzinX

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

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

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


我在 Gries 或 Djikstra 的某个地方读到,将逻辑运算符放在行的最前面 - 让更多可见 - 有帮助。自 90 年代以来,我一直在这样做。它有帮助。
请注意,样式指南建议将条件放在行尾。
这是真的,虽然我从来不同意这一点。毕竟,这只是一个指南。
PEP8 no longer recommends 将条件放在行尾。
M
Mark Amery

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

当 if 语句的条件部分足够长以至于需要跨多行编写时,值得注意的是,两个字符的关键字(即 if )加上一个空格,再加上一个左括号会创建一个自然的多行条件的后续行的 4 个空格缩进。这可能会与嵌套在 if 语句中的缩进代码套件产生视觉冲突,该代码也自然缩进为 4 个空格。这个 PEP 没有明确说明如何(或是否)进一步在视觉上将这些条件行与 if 语句内的嵌套套件区分开来。在这种情况下可接受的选项包括但不限于: # 没有额外的缩进。 if (this_is_one_thing and that_is_another_thing): do_something() # 添加注释,这将在编辑器中提供一些区别 # 支持语法高亮。 if (this_is_one_thing 和 that_is_another_thing): # 因为这两个条件都为真,所以我们可以互相攻击。 do_something() # 在条件续行上添加一些额外的缩进。 if (this_is_one_thing 和 that_is_another_thing): do_something()

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


+1 为 PEP8。这应该被接受,因为它(实际上)是官方的 Python 风格指南。
同样值得强调的是,PEP8 明确表明其立场,因为此 PEP 没有明确表示如何(或是否)进一步在视觉上将这些条件行与 if 语句内的嵌套套件区分开来。在这种情况下可接受的选择包括但不限于:...(剪断)所以,停止争论,选择你喜欢的东西!
z
zkanda

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

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

if all(condition):
   do_something

如果您想在 cond4 中检查函数或 cond2cond1 的属性,则情况不好。示例条件:object is not None and object.param == 5 and object.is_running()
在这一点上,为什么不只是 condition = cond1 == 'val1' and cond2 == 'val2' ...?更清晰(没有分离逻辑运算符和条件)并保留短路行为。
r
rgenito

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

英语:“如果登录用户不是管理员教师,而只是普通教师,本身又不是学生……”

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

当然这可能看起来不错,但是阅读那些 if 语句是很多工作。我们如何将逻辑分配给有意义的标签。 “标签”实际上是变量名:

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

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

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

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


A
Apalala

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

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

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


除此之外,您可以声明一个函数或 lambda 以返回您的真假,而不是创建一个额外的变量。
@Techdragon 如果条件要在其他地方,那么将它们放入 lambda 块将需要命名 lambda 块,以便稍后在 if 条件中引用它。如果要命名一个 lambda,为什么它而不是一个常规函数呢?我个人喜欢这种简化的布尔表达式。
我同意,这就是为什么我通常会在大多数情况下使用一个函数来提高可读性和在略读理解程序控制流时便于精神消化。我提到 lambda 是为了确保“更小”选项也存在,以防人们特别注重空间。
这很酷。不幸的是,如果我在变量子句中包含 Path(input).is_dir()Path(input).is_file(),我会收到 TypeError: 'bool' object is not callable
F
Fred Nurk

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

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

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

由于我从 your blog post about C++ 中发现了这个问题,因此我将说明我的 C++ 风格是相同的:

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

M
Marius Gedminas

我很惊讶没有看到我喜欢的解决方案,

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

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


但是续行仍然无法与下一个逻辑行区分开来......
请注意,这是 PEP 0008 违规(“绕过二元运算符的首选位置是在运算符之后,而不是在它之前”)。当然,您是否关心取决于您。
顺便说一句,这不再是我的首选解决方案。 ;)
C
Community

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

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

最近我更喜欢 allany 函数,因为我很少混合 And 和 Or 比较,这很有效,并且具有生成器理解的早期失败的额外优势:

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

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

注意:any 类似于许多 or 比较,all 类似于许多 and 比较。

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

# 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!")

更多信息:generator comprehension


我还应该指出,pylint 的库存配置需要在 if 中继续缩进;这阻止了我使用这个方案。
A
Anders Waldenborg

“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

不正确!他们这样做只是因为你这样做。尝试 all(f() for f in [c1, c2])。
我认为他只是将函数用作示例,因为他可以轻松地让它们打印一些东西。如果我们正在考虑在列表中提供给 all() 的一系列任意表达式,那么除非您将每个表达式包装在 lambda 中并使用您的 f() 技巧,否则它们都将被评估。换句话说,Aaron:我认为 Anders 试图谈论一般的条件,使用可调用对象作为具体示例;但您的反驳仅适用于功能。
F
Federico A. Ramponi

如果我们只在条件和正文之间插入一个额外的空行并以规范的方式完成其余的工作呢?

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

    do_something

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


我认为这将非常令人困惑,尤其是当条件的主体很长时。
我同意 Eli 的观点,这里的封装和缩进让长行感到困惑。此外,the new ruleandor 语句应该从下一行开始
t
tomekwi

我通常做的是:

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

这样,右大括号和冒号在视觉上标志着我们条件的结束。


几乎正确; PEP 8 现在建议在 andor 之前中断。
S
SMGreenfield

我知道这个线程很旧,但我有一些 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 能咬紧牙关,只带花括号。我想知道这些年来由于意外的错误缩进而意外引入了多少错误......


这是一个糟糕的设计AFAIK。我的意思是,如果我们必须进行这种编码,我们应该重新考虑我们的代码。 TBH 我有同样的问题。我是Node.js出身,在那个维度我们不关心这个问题,直接说根本不是问题。在 node.js 中,我们有更漂亮的。顺便说一句,我想在那种情况下,如果我们有教条的话,我们应该改变我们的教条信念。
S
Stof

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

即使是 PEP 0008 的答案也令人反感。

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

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

要我吃我的话?说服我您需要多条件,我会逐字打印并吃掉它以供您娱乐。


这确实是一种非常巧妙的多条件处理方式:) 不知道为什么它没有更多的选票:),有什么注意事项吗?
@SaulCruz 真的没有 不仅不需要重复条件变量,还可以节省检查每个值的许多重复项,这只是将值放入数组中,让引擎完成它的(优化)工作为您检查病情
@Stoff 感谢您删除我的评论。我想指出您的方法不能回答 OP 的问题。您提供的代码不能应用于问题中的代码。如果您不这么认为,那么您应该添加通过您的方法重新格式化的 OP 代码来证明您的观点。
这不是公认的答案,但它显然是一种替代方法(其他人同意)。所以鼓励替代答案,那么究竟是什么论点?在你自己的问题中要清楚,如果你需要适当的关注,也许可以考虑打开你自己的问题。 PS我不是SO mod,我不能删除评论
r
ryanjdillon

我认为@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 operator 抛出另一个解决方案:

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

if proceed:
    # do something

只是为了好玩:all(map(eq, have, expected))。 (与 from operator import eq
J
Jason Baker

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

你也可以用字典来做到这一点:

>>> 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'

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

(并且为了记录,如果这只是一次性的事情,你可能最好使用你最初提出的方法。如果你在很多地方进行比较,这些方法可能会增强可读性,足以使你对他们有点老套这一事实并不感到难过。)


E
El Ninja Trepador

我也一直在努力寻找一种体面的方法来做到这一点,所以我只是想出了一个主意(不是灵丹妙药,因为这主要是一个品味问题)。

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

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

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

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

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

无论如何,还有两个我在这里没有看到的建议。希望这可以帮助某人:)


S
SarcasticSully

你可以把它分成两行

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

甚至一次添加一个条件。这样,至少它将混乱与 if 分开。


p
psihodelia

把你的条件打包成一个列表,然后做某事。喜欢:

if False not in Conditions:
    do_something

x
xorsyst

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

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

@qarma,您愿意扩展吗?这肯定比使用 PEP 8 推荐的换行符更好
这实际上是行延续的有效案例。 IMPO 括号表示元组或函数调用。 OP 的使用非常类似于 C,我尽可能喜欢 python 语法。我承认 \ 并不是普遍受欢迎的。
D
Dima Tisnek
  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


Google 的指南还提供了 an example of a complex condition,它与 OP 提到的“最明显的方法”相匹配。尽管该指南并未明确提倡以这种方式格式化长“if”。
u
user1487551

这是另一种方法:

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"')

A
Artur Gaspar

我通常使用:

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

G
Gautam

如果我们的 if 和 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

N
Nader Belal

请原谅我的菜鸟,但碰巧我不像你们这里的任何人一样了解#Python,但碰巧我在 3D BIM 建模中编写自己的对象脚本时发现了类似的东西,所以我将调整我的算法以蟒蛇。

我在这里发现的问题是双面的:

对于可能试图破译剧本的人来说,我的价值观似乎很陌生。如果更改了这些值(最有可能),或者如果必须添加新条件(损坏的模式),代码维护将付出高昂的代价

绕过所有这些问题,你的脚本必须像这样

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

这种方法的优点:

脚本可读。脚本易于维护。 conditions 是对表示所需条件的值之和的 1 比较操作。无需多级条件

希望对大家有帮助