在 Python 中不在一行中做一个简单的 if-else 语句是不好的做法吗?

Is it bad practice to make a simple if-else statement not on one single line in Python?

在实习期间,我注意到我的一位同事通过这样做操纵了我的一项职能:

if isSinglesMatch:
    name1 = GetName(1, "BUG")
    name2 = GetName(2, "BUG")
else:
    name1 = GetName(1, "Short")
    name2 = GetName(2, "Short")

对此:

name1 = GetName(1, "BUG" if isSinglesMatch else "Short")
name2 = GetName(2, "BUG" if isSinglesMatch else "Short")

我看到他的代码更短了,但是有没有解释速度更快的优点?保持它最初的样子不好吗?在我看来,调试我的代码更容易(我在这个例子中遗漏了一些额外的变量赋值)。

实习期间没有人告诉我应该改变做事的方式,我只是注意到我的同事喜欢这样做。

在我看来,两行相同的条件更糟糕。你的代码更容易理解。最好是:

mode = "BUG" if is_singles_match else "Short"
name1 = get_name(1, mode)
name2 = get_name(2, mode)

注意命名约定。

如果您对解释器的影响感到好奇,可以随时使用 dis。我很好奇所以 运行 我自己:

我添加了一些序言只是为了定义 GetNameisSinglesMatch,但这是您的示例的反汇编代码:

  1           0 LOAD_CONST               0 (False)
              2 STORE_NAME               0 (isSinglesMatch)

  2           4 LOAD_CONST               1 (<code object GetName at 0x7f4e90337810, file "test_a.py", line 2>)
              6 LOAD_CONST               2 ('GetName')
              8 MAKE_FUNCTION            0
             10 STORE_NAME               1 (GetName)

  5          12 LOAD_NAME                0 (isSinglesMatch)
             14 POP_JUMP_IF_FALSE       38

  6          16 LOAD_NAME                1 (GetName)
             18 LOAD_CONST               3 (1)
             20 LOAD_CONST               4 ('BUG')
             22 CALL_FUNCTION            2
             24 STORE_NAME               2 (name1)

  7          26 LOAD_NAME                1 (GetName)
             28 LOAD_CONST               5 (2)
             30 LOAD_CONST               4 ('BUG')
             32 CALL_FUNCTION            2
             34 STORE_NAME               3 (name2)
             36 JUMP_FORWARD            20 (to 58)

  9     >>   38 LOAD_NAME                1 (GetName)
             40 LOAD_CONST               3 (1)
             42 LOAD_CONST               6 ('Short')
             44 CALL_FUNCTION            2
             46 STORE_NAME               2 (name1)

 10          48 LOAD_NAME                1 (GetName)
             50 LOAD_CONST               5 (2)
             52 LOAD_CONST               6 ('Short')
             54 CALL_FUNCTION            2
             56 STORE_NAME               3 (name2)
        >>   58 LOAD_CONST               7 (None)
             60 RETURN_VALUE

更简洁的版本:

  1           0 LOAD_CONST               0 (False)
              2 STORE_NAME               0 (isSinglesMatch)

  2           4 LOAD_CONST               1 (<code object GetName at 0x7f13f8f1f810, file "test_a.py", line 2>)
              6 LOAD_CONST               2 ('GetName')
              8 MAKE_FUNCTION            0
             10 STORE_NAME               1 (GetName)

  5          12 LOAD_NAME                1 (GetName)
             14 LOAD_CONST               3 (1)
             16 LOAD_NAME                0 (isSinglesMatch)
             18 POP_JUMP_IF_FALSE       24
             20 LOAD_CONST               4 ('BUG')
             22 JUMP_FORWARD             2 (to 26)
        >>   24 LOAD_CONST               5 ('Short')
        >>   26 CALL_FUNCTION            2
             28 STORE_NAME               2 (name1)

  6          30 LOAD_NAME                1 (GetName)
             32 LOAD_CONST               6 (2)
             34 LOAD_NAME                0 (isSinglesMatch)
             36 POP_JUMP_IF_FALSE       42
             38 LOAD_CONST               4 ('BUG')
             40 JUMP_FORWARD             2 (to 44)
        >>   42 LOAD_CONST               5 ('Short')
        >>   44 CALL_FUNCTION            2
             46 STORE_NAME               3 (name2)
             48 LOAD_CONST               7 (None)
             50 RETURN_VALUE

忽略 MAKE_FUNCTION/STORE_NAME 之前的所有内容,您会发现性能成本略有不同。但是,为了可读性,我个人会牺牲这种情况下的性能。

编程很自以为是,他这样做大概是有原因的。 一是为了可读性。很多时候,开发人员为了易于阅读而牺牲了微不足道的性能下降。如果您有易于阅读的代码,那么维护它就不会像难以阅读的那样痛苦。

我认为在这种情况下你必须问问你的同事。他们可能遵循一些您可能不熟悉的代码风格。

这不是一个坏习惯。这只是取决于你在哪里使用它。

我注意到几家公司采用相同的标准。通常,条件语句将被缩短为一行——通过三元运算符——因此代码看起来更简洁。

如果条件很简单,那就太好了。在您提供的示例中,修改后的代码更清晰,两个变量 name1name2 仅声明一次。

虽然原始代码可以正常工作,但可以将修订版视为做同样事情的简化方式

如果您想确定何时应该分解条件,请考虑是否可以将其编写得更简单(同时仍然可以理解)。如果它导致多个嵌套的三元运算符,在这种情况下最好避免它。