2011-12-06 9 views
13

Debido a las reglas de alcance de Python, todas las variables una vez inicializadas dentro de un alcance están disponibles a partir de entonces. Como los condicionales no introducen un nuevo ámbito, las construcciones en otros lenguajes (como la inicialización de una variable antes de esa condición) no son necesariamente necesarias. Por ejemplo, podríamos tener:¿Cuál es la forma pitonica de inicialización de variable condicional?

def foo(optionalvar = None): 
    # some processing, resulting in... 
    message = get_message() 
    if optionalvar is not None: 
     # some other processing, resulting in... 
     message = get_other_message() 
    # ... rest of function that uses message 

o, podríamos tener lugar:

def foo(optionalvar = None): 
    if optionalvar is None: 
     # processing, resulting in... 
     message = get_message() 
    else: 
     # other processing, resulting in... 
     message = get_other_message() 
    # ... rest of function that uses message 

Por supuesto, los get_message y get_other_message funciones podrían ser muchas líneas de código y son básicamente irrelevante (se puede asumir que el estado del programa después de cada ruta es el mismo); el objetivo aquí es hacer que message esté listo para usar más allá de esta sección de la función.

he visto el último constructo utilizado varias veces en otras preguntas, tales como:

que construyen sería más aceptable?

+1

que no dependen por completo si desea 'get_message' para ejecutar condicional o incondicional? – delnan

+0

La idea aquí no es la función de llamar, sino la construcción de 'mensaje': la función en sí misma es irrelevante. –

+1

Tanto si se trata de una función como si no, la única diferencia semántica es que se ejecuta la mitad del código incondicionalmente. Si hace una diferencia, no tiene mucho sentido debatir el estilo. – delnan

Respuesta

12

Python también tiene una gran utilidad si el patrón de sintaxis que se puede utilizar aquí

message = get_other_message() if optional_var else get_message() 

O si lo desea comparar estrictamente Ninguno

message = get_other_message() if optional_var is not None else get_message() 

diferencia con el ejemplo 1) informados Esto no tiene No llame a get_message() innecesariamente.

+1

Esta es ** LA ** manera pitonica de realizar asignaciones condicionales (desde la v2.5), al menos en lo que se refiere al lenguaje en sí. Consulte [PEP 308] (http://docs.python.org/release/2.5/whatsnew/pep-308.html) para obtener más información. – voithos

+0

También parece que PEP 308 sugiere que el segundo formato fue la forma aceptable anterior de hacer esto. ¡Bueno saber! –

1

Creo que es más tonto no establecer una regla explícita sobre esto, y en cambio solo mantener la idea de que las funciones pequeñas son mejores (en parte porque es posible tenerlo en cuenta cuando se introducen nuevos nombres).

supongo embargo que si sus pruebas condicionales consiguen mucho más complicado que un if/else puede correr el riesgo de todos ellos en su defecto, y luego usando un nombre no definido, dando lugar a un posible error de ejecución, a menos que usted es muy cuidadoso. Eso podría ser un argumento para el primer estilo, cuando sea posible.

0

La respuesta depende de si hay efectos secundarios de get_message() que se desean.

En la mayoría de los casos, gana claramente el segundo, porque el código que produce el resultado no deseado no se ejecuta. Pero si necesita los efectos secundarios, debe elegir la primera versión.

0

Podría ser mejor (leer: más seguro) inicializar su variable fuera de las condiciones. Si tiene que definir otras condiciones o incluso eliminar algunas, el usuario de message más adelante podría obtener una excepción de variable no inicializada.

4

En general, el segundo enfoque es mejor y más genérico porque no implica la llamada incondicional a get_message.Los cuales puede estar bien si esa función no es de recursos incentivo pero tenga en cuenta una función de búsqueda

def search(engine): 
    results = get_from_google() 
    if engine == 'bing': 
     results = get_from_bing() 

, obviamente, esto no es bueno, no puedo pensar en tal mal escenario para el segundo caso, por lo que, básicamente, un enfoque que va a través de todo opciones y, finalmente, ¿el valor predeterminado es el mejor, por ejemplo,

def search(engine): 
    if engine == 'bing': 
     results = get_from_bing() 
    else: 
     results = get_from_google() 
Cuestiones relacionadas