2008-09-25 8 views

Respuesta

23

En Python 2.5, hay

A if C else B 

que se comporta muy parecido a:? En C. Sin embargo, está mal visto por dos razones: la legibilidad, y el hecho de que por lo general hay una manera más sencilla de acercarse a la problema. Por ejemplo, en su caso:

stringValue = otherString or defaultString 
+0

El segundo ejemplo/funciona /, pero vea mi comentario sobre cómo puede especificar la comparación. –

+2

¿No es eso al revés?En general, el y/o truco está mal visto debido a errores como "cond y A o B", donde A resulta ser un valor falso como 0. Hay soluciones como (cond y [A] o [B]) [0 ], pero la sintaxis if/else se agregó prácticamente para eliminar la necesidad de tal abuso. – Brian

+1

No es al revés. La sintaxis if/else se agregó para 'corregir' la necesidad que tenían las personas de un operador ternario que los condujera a la rotura y/o al truco. Sin embargo, observe cómo mi ejemplo no usa 'y'. Solo usa 'o', que es una forma mucho más directa de hacer lo que el OP quería. No hay gotcha allí. –

1

Nunca es malo escribir un código legible y expresivo.

if otherString: 
    stringValue = otherString 
else: 
    stringValue = defaultString 

Este tipo de código es más largo y más expresivo, pero también más fácil de leer y menos propensos a tropezar con él o mal-editada por el camino. No tengas miedo de escribir expresivamente: el código legible debe ser un objetivo, no un subproducto.

-1

Puede aprovechar el hecho de que las expresiones lógicas devuelven su valor, y no solo el estado verdadero o falso. Por ejemplo, siempre se puede utilizar:

result = question and firstanswer or secondanswer 

Con la advertencia de que no funciona como el operador ternario si firstanswer es falsa. Esto se debe a que la pregunta se evalúa primero, suponiendo que es verdadera primero se devuelve a menos que primero sea falsa, por lo que este uso no actúa como el operador ternario. Sin embargo, si conoce los valores, generalmente no hay problema. Un ejemplo sería:

result = choice == 7 and "Seven" or "Another Choice" 
5

@ Dan

if otherString: 
    stringValue = otherString 
else: 
    stringValue = defaultString 

Este tipo de código es más largo y más expresivo, pero también más legible

Pues sí, es más largo. No estoy tan seguro de "más expresivo" y "más legible". Por lo menos, su reclamo es discutible. Incluso llegaría a decir que es francamente erróneo, por dos razones.

En primer lugar, su código enfatiza la toma de decisiones (bastante extrema). Por otro lado, el operador condicional enfatiza otra cosa, a saber, el valor (o la asignación de dicho valor). Y esto es exactamente lo que quiere el autor de este código. La toma de decisiones es más bien un subproducto del código. La parte importante aquí es la operación de asignación. Su código oculta esta tarea en un montón de ruido sintáctico: la ramificación.

Su código es menos expresivo porque cambia el énfasis de la parte importante.

Incluso entonces su código probablemente superaría algún arte ASCII oscuro como ?:. Un en línea- if sería preferible. Personalmente, no me gusta la variante presentada con Python 2.5 porque está al revés.Yo preferiría algo que se lee en el mismo flujo (dirección) como el operador ternario C pero usa palabras en lugar de caracteres ASCII:

C = if cond then A else B 

Este gana sin esfuerzo.

C y C# lamentablemente no tienen una declaración tan expresiva. Pero (y este es el segundo argumento), el operador condicional ternario de las lenguas C está tan arraigado que se ha convertido en un modismo en sí mismo. El operador ternario es tan parte del lenguaje como la declaración "convencional" if. Debido a que es una expresión idiomática, cualquiera que conozca el idioma inmediatamente lee este código correctamente. Además, es una forma extremadamente corta y concisa de expresar estas semánticas. De hecho, es la forma más corta imaginable. Es extremadamente expresivo porque no oscurece la esencia con ruido innecesario.

Finalmente, Jeff Atwood ha escrito la conclusión perfecta para esto: The best code is no code at all.

+0

Corrígeme si crees que estoy equivocado, pero esto debería ser un comentario a la publicación de Dan en lugar de una nueva respuesta. Tiene razón acerca de que su respuesta es discutible/discutible, pero yo diría que ha ido demasiado lejos al decir "muy mal". Eso es sólo decir ... (La mayoría de los físicos se paran en los hombros mientras que la mayoría de los informáticos se ponen de puntillas). – Pretzel

+0

Por cierto, entiendo por qué sentiste la necesidad de responder como una respuesta, en lugar de un comentario. . (Stackoverflow no me permitió editar mi comentario ...) – Pretzel

0

Por cierto, j0rd4n, usted no (por favor no!) Escriba un código como este en C#. Aparte del hecho de que el IsDefaultOrNull se llama realmente IsNullOrEmpty, esto es puro código de hinchazón. C# ofrece el operador se unen para situaciones como estas:

string stringValue = otherString ?? defaultString; 

Es cierto que esto sólo funciona si otherString es null (en lugar de vacío), pero si esto se puede asegurar de antemano (y con frecuencia se puede) que hace que el código mucho más legible

+0

Este es un buen punto (como acabo de enterarme del operador de fusión un par de semanas atrás, pero ¿qué pasa con el caso en que las cadenas vacías son devueltas de una consulta de base de datos? ? Gran parte del código que escribo utiliza la API de base de datos de nuestra empresa, que devuelve cadenas vacías mucho. –

+0

En referencia a mi ejemplo de ruby, escribí un método de extensión IsBlank en C# que hace eso. No sé qué harías en Python –

-1

Si utilizó rubí, se podría escribir

stringValue = otherString.blank? ? defaultString : otherString; 

el construido en blank? método significa nulo o vacío.
Acércate al lado oscuro ...

0

También descubrí que usar el operador "or" funciona bastante bien. Por ejemplo:

finalString = get_override() or defaultString 

Si get_override() vuelve "" o ninguno, se utilizará siempre defaultString.

1

Hay algunos duplicados de esta pregunta, p.

En esencia, en un entorno general de pre-2,5 código debe utilizar este:

(condExp and [thenExp] or [elseExp])[0] 

(dado condExp, thenExp y elseExp son expresiones arbitrarias) , ya que evita los resultados incorrectos si thenExp evalúa a boolean False, mientras se mantiene la evaluación de cortocircuito.

Cuestiones relacionadas