t = (1, 2)
print t
## (1, 2)
print type(t)
##
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())
##
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