2013-10-02 3 views
2

Je viens de lire la ligne suivante dans un script:Que signifie cette comparaison?

fn = (len(sys.argv) > 2 and [sys.argv[2]] or ['test_out.jpg'])[0] 

Je ne vraiment pas obtenir ce qui se passe ici. Il y a donc une comparaison du nombre d'arguments avec 2 puis une déclaration ou. Que fait l'auteur avec cela et est-ce un bon style de codage?

Répondre

3

Personnellement, je trouve mauvais style de codage, car il est pas évident ce qui se passe (donc, votre question).

Qu'est-ce qu'il fait:

  1. Voir si sys.argv a plus de 2 articles
  2. Si elle a plus de 2 articles, retour [sys.argv[2]]
  3. Sinon, le retour ['test_out.jpg']
  4. Depuis le précédent retour item (qui est toujours une liste), renvoyer l'élément 0.

A mpler version serait:

fn = sys.argv[2:] and sys.argv[2] or 'test_out.jpg' 

Une version plus lisible:

fn = sys.argv[2] if sys.argv[2:] else 'test_out.jpg' 
+0

merci - ne savait pas 'sys.argv [2:]' était fonctionnellement équivalent à 'len (sys.argv)> 2' ... –

5
fn = (len(sys.argv) > 2 and [sys.argv[2]] or ['test_out.jpg'])[0] 

est comme:

fn = ([sys.argv[2]] if len(sys.argv) > 2 else ['test_out.jpg'])[0] 

Dans des déclarations simples:

if len(sys.argv) > 2: 
    fn = [sys.argv[2]][0] 
else: 
    fn = ['test_out.jpg'][0] 

Comme vous pouvez le voir [...][0] est un peu redondant. Donc déclaration originale pourrait être replacecd comme suit:

fn = len(sys.argv) > 2 and sys.argv[2] or 'test_out.jpg' 

MISE À JOUR code ci-dessus ne fonctionnera pas si sys.argv[2] est une chaîne vide. C'est pourquoi le code original utilise le formulaire [...][0]. Il faut donc utiliser si possible formulaire ci-dessous:

fn = sys.argv[2] if len(sys.argv) > 2 else 'test_out.jpg' 
+0

Probablement un vestige de pré-2.5 ère, avant PEP308 a été introduit. – fjarri

+0

Merci pour la réponse rapide. Je ne suis pas un locuteur natif anglais donc j'ai du mal à trouver ce code court dans la documentation. Comment ça s'appelle? – JasonTS

+0

@JasonTS Il est similaire à [expression conditionnelle] (http://docs.python.org/2/reference/expressions.html#conditional-expressions) – TerryA

0

and et or agissent en python comme un court-circuit dans certains cas.

Dans une expression x and y, si x est évalué à False, il n'est pas nécessaire de regarder y car le résultat sera faux. Dites, vous voulez obtenir sys.argv[2], mais seulement dans le cas où il y a assez d'arguments. Ensuite, vous pouvez faire:

len (sys.argv)> 2 et [sys.argv [2]]

Donc, si sys.argv a une longueur de 2 ou moins, len(sys.argv) > 2 évaluera false et il ne évaluer sys.argv[2] (et donc ne pas courir dans un IndexError).

De même, dans une expression x or y, que lorsque x est évaluée à False sera y évaluer.Par conséquent, si le nombre d'arguments est inférieur ou égal à 2, fn prendra la valeur ['test_out.jpg']. Enfin, les parenthèses sont ensuite pour obtenir l'index zéro en utilisant le [0] final dans l'expression

En résumé: si le nombre d'arguments est 2 ou plus, affectez fn à sys.argv[2], sinon attribuez fn à 'test.out.jpg'.