PROJET AUTOBLOG


Sam et Max

source: Sam et Max

⇐ retour index

La virgule n’est pas un opérateur en Python

vendredi 22 février 2013 à 11:57

Premiers tutos, et vous apprenez l’existence du tuple :

t = (1, 2)
print t
## (1, 2)
print type(t)
## <type 'tuple'>

Puis en creusant un peu, vous apprenez qu’un tuple, en fait, c’est juste une série d’objets séparés par des virgules :

t = 1, 2
print t
## (1, 2)

Les parenthèses sont optionnelles pour créer un tuple.

Du coup si on rajoute l’unpacking :

a, b = (1, 2)
print a
## 1
print b
## 2

Du coup on peut faire des fonctions qui semblent (mais c’est une illusion), retourner plusieurs valeurs à la fois :

def foo():
    return 1, 2
 
print foo()
## (1, 2)
print type(foo())
## <type 'tuple'>
a, b = foo()
print a
## 1
print b
## 2

Mais un jour, au lieu de faire ça :

t = "a" in ("b", "a")
print t
## True

Vous faites ça

t = "a" in "b", "a"
print t
## (False, 'a')

Enfer, damnation et baba au rhum !

Ce n’est pas du tout ce que vous attendiez !

La raison à cela est que la virgule en Python n’est pas un opérateur, c’est un simple séparateur. Votre expression a donc été analysée comme :

("a" in "b"), "a"

C’est pour cela qu’utiliser les parenthèses est recommandé avec les tuples : pour clarifier la priorisation des opérations. Car comme la virgule n’est pas un opérateur, elle n’a pas de priorité définie comme pour *, /, and et or, et c’est un peu la fête du slip.

Moralité : à part pour l’unpacking, utilisez toujours des parenthèses dans vos tuples.

Ça vous évitera des aventures du genre :

s = "Ceci est un %s %s" % "test", "idiot"
## TypeError: not enough arguments for format string
print s
 
s = "Ceci est un %s" % "test", "idiot"
print s
## ('Ceci est un test', 'idiot')
 
s = "Ceci est un %s %s" % ("test", "idiot")
print s
## Ceci est un test idiot

Télécharger le code source de ce tuto

flattr this!