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
Ca donne quoi en python3 sinon ?
Ça donne des erreurs sur les print ! ;)
Sinon, je ne crois pas que ça ait changé de ce point de vue.
(edit) En tout cas, le dernier bloc de code donne les mêmes résultats.
La virgule n’est pas devenu un opérateur en Python 3, donc ça change rien. Print et format sont des fonctions, et la virgule dans la fonction est le séparateur des arguments, ce qui fonctionne de la même manière qu’en Python 2.
Ouf! on a eu chaud!
Pour ça que, vu qu’il s’agit toujours de tuple avec ou sans les parenthèses, j’essaye de toujours les mettre, pour éviter ce genre de confusion :)
Mais c’est une bonne idée de le souligner, notamment pour ceux qui l’ignoraient.