2012-05-15 15 views
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() 

En cuanto al estilo de codificación: A menudo uso el primero cuando los siguientes bloques, o el último bloque es una gran porción de código. Parece ayudar a la legibilidad.¿Debo usar elif si ya he regresado de la función en un bloque anterior?

Generalmente utilizo este último cuando los diversos bloques tienen un concepto común que los atraviesa (como en el caso anterior). La sangría común ayuda a comunicar su relación.

¿Hay alguna diferencia entre estos dos aspectos importantes (especialmente el rendimiento)?

+4

el segundo ejemplo es más legible imo. – jamylak

Respuesta

6

En cuanto al estilo, el segundo ejemplo me resulta más fácil a simple vista.

En todos los demás aspectos, no hay diferencia. Las dos funciones compilan a bytecodes idénticos:

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   

(. Para ser 100% exacto, la segunda versión tiene un implícito return None al final Sin embargo, ya que este código no es accesible, se no afecta al rendimiento.)

0

Solo puede conocer el rendimiento de un caso específico mediante la evaluación comparativa/cronometraje (o como muestra @aix, mirando el código traducido, suponiendo que el segmento de código es suficientemente pequeño).

Habiendo dicho eso, creo que la semántica del segundo ejemplo es más clara ya que el constructo de lenguaje muestra que las opciones son mutuamente excluyentes.

En general, dada la misma funcionalidad, una cláusula if/elif/else debe ser más eficiente que una serie de if -statement donde múltiples if estados pueden ser ejecutadas/evaluados en secuencia incluso si un anterior if se ha encontrado para ser verdad. En este ejemplo de código específico, este no es el caso, ya que se ejecuta un return tan pronto como se ejecuta el cuerpo apropiado de la declaración if.

Cuestiones relacionadas