7
def size(number):
    if number<100:
        return Small()

    if number<1000:
        return Medium()

    return Big()

def size1(number):
    if number<100:
        return Small()
    elif number<1000:
        return Medium()
    else:
        return Big()

关于编码风格:当后面的块,或者最后一个块是一大块代码时,我经常使用前者。这似乎有助于提高可读性。

当各种块有一个共同的概念贯穿它们时,我通常使用后者(如上例所示)。共同的缩进有助于传达他们的关系。

这两者之间是否有任何值得注意的差异(尤其是性能方面)?

4

2 回答 2

6

风格方面,我发现第二个例子更容易理解。

在所有其他方面,没有区别。这两个函数编译为相同的字节码:

In [3]: dis.dis(size)
  2           0 LOAD_FAST                0 (number)
              3 LOAD_CONST               1 (100)
              6 COMPARE_OP               0 (<)
              9 POP_JUMP_IF_FALSE       19

  3          12 LOAD_GLOBAL              0 (Small)
             15 CALL_FUNCTION            0
             18 RETURN_VALUE        

  5     >>   19 LOAD_FAST                0 (number)
             22 LOAD_CONST               2 (1000)
             25 COMPARE_OP               0 (<)
             28 POP_JUMP_IF_FALSE       38

  6          31 LOAD_GLOBAL              1 (Medium)
             34 CALL_FUNCTION            0
             37 RETURN_VALUE        

  8     >>   38 LOAD_GLOBAL              2 (Big)
             41 CALL_FUNCTION            0
             44 RETURN_VALUE        

In [4]: dis.dis(size1)
 11           0 LOAD_FAST                0 (number)
              3 LOAD_CONST               1 (100)
              6 COMPARE_OP               0 (<)
              9 POP_JUMP_IF_FALSE       19

 12          12 LOAD_GLOBAL              0 (Small)
             15 CALL_FUNCTION            0
             18 RETURN_VALUE        

 13     >>   19 LOAD_FAST                0 (number)
             22 LOAD_CONST               2 (1000)
             25 COMPARE_OP               0 (<)
             28 POP_JUMP_IF_FALSE       38

 14          31 LOAD_GLOBAL              1 (Medium)
             34 CALL_FUNCTION            0
             37 RETURN_VALUE        

 16     >>   38 LOAD_GLOBAL              2 (Big)
             41 CALL_FUNCTION            0
             44 RETURN_VALUE        
             45 LOAD_CONST               0 (None)
             48 RETURN_VALUE        

(为了 100% 准确,第二个版本return None的末尾有一个隐式。但是,由于此代码不可访问,因此不会影响性能。)

于 2012-05-15T11:01:42.367 回答
0

您只能通过对其进行基准测试/计时(或如@aix 所示,查看翻译后的代码,假设代码段足够小)来了解特定案例的性能。

话虽如此,我认为第二个示例的语义更清晰,因为语言结构表明选项是互斥的。

一般来说,给定相同的功能,一个if/elif/else子句应该比一系列if-statement 更有效,其中多个if语句可以按顺序执行/评估,即使先前if已被发现是正确的。在这个特定的代码示例中,情况并非如此,因为return一旦执行了适当的if语句主体,就会执行。

于 2012-05-15T10:59:44.970 回答