Il peut être intéressant à plusieurs titre de stocker des résultats intermédiaires d’un calcul. Ceci est accompli en python au moyen de variable. On crée une variable de la façon simple suivante en utilisant le symbole =.
>>> x = 1On peut alors utiliser x à la place de 1 comme on le souhaite.
>>> x = 1
>>> x + 1
2
>>> 2 * x
2
>>> x ** x
1On peut mettre une expression arbitrairement complexe à la droite du symbole = celle-ci sera évaluée avant d’être affectée. Les parenthèses serviront à préciser l’ordre dans lequel l’évaluation est effectuée.
>>> x = (1 + 2 * (3 ** 4)) % 5
>>> x
3On peut également utiliser une variable dans l’expression à droite.
>>> x = 1
>>> y = x + 1
>>> x
1
>>> y
2C’est même le cas si on réutilise le nom
>>> x = 1
>>> x
1
>>> x = x + 1
>>> x
2à condition que toutes les variables de droites aient bien été définies précédemment.
>>> x = x + 1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not definedLes noms de variables peuvent être constitués de minuscule (a à z), majuscules (A à Z) de chiffres (0 à 9) et du caractère underscore (_).
>>> mon_entier_a_moi = 1
>>> mon_entier_a_moi
1
>>> le_nombre_2 = 2
>>> le_nombre_2
2Les espaces ne sont pas autorisés!
>>> x y = 1
File "<stdin>", line 1
x y = 1
^
SyntaxError: invalid syntaxIl n’est pas possible de commencer par un chiffre.
>>> 12ab = 1
File "<stdin>", line 1
12ab = 1
^
SyntaxError: invalid syntaxPar convention en python
class)_ sont considérées comme privé on les évitera avant de bien comprendre les implicationsles mots à l’intérieur d’un nom sont séparés par des _, convention dite snake_case par opposition à la convention camelCase ainsi on préferea
>>> mon_entier = 1
>>> mon_entier
1à
>>> monEntier = 1
>>> monEntier
1Finalement l’appel à la fonction vars permet de voir les variables existant déjà à ce stade de l’exécution (elle renvoit une structure dict que l’on verra plus tard)
>>> vars()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>}
>>> x = 1
>>> vars()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'x': 1}
>>> y = 2
>>> vars()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'x': 1, 'y': 2}Les variables sont utiles au moins à deux titres. 1. Elles permettent tout d’abord de stocker des résultats intermédiaires dans une procédure compliquée. 2. La possibilité de donner un nom permet si celui-ci est bien choisi d’éclairer le lecteur. Comparer ainsi les deux versions de la procédure calculant le nombre de secondes dans un siècle.
>>> 25 * 366 * 24 * 60 * 60 + 75 * 365 * 24 * 60 * 60
3155760000>>> secondes_dans_minute = 60
>>> minutes_dans_heure = 60
>>> heures_dans_journee = 24
>>> secondes_par_jour = secondes_dans_minute * minutes_dans_heure * heures_dans_journee
>>> secondes_par_jour
86400
>>> nombre_annees_bisextiles = 25
>>> nombre_annees_regulieres = 75
>>> jours_dans_annee_reguliere = 365
>>> jours_dans_annee_bisextile = 366
>>> jours_par_siecle = nombre_annees_bisextiles * jours_dans_annee_bisextile + nombre_annees_regulieres * jours_dans_annee_reguliere
>>> jours_par_siecle
36525
>>> secondes_par_siecles = jours_par_siecle * secondes_par_jour
>>> secondes_par_siecles
3155760000La seconde version
60!La seconde version peut paraître inutilement verbeuse.
python standard par ipython pour s’en convaincre.En conclusion le nommage d’une variable n’est pas quelque chose à prendre à la légère et on n’hésitera pas à renommer des variables si un meilleur nom vient en tête!
Il faut faire attention à une subtilité conduisant à des bugs délicats mais fréquents!
Les variables ne doivent pas être confondues avec les objets python sous jacents! Il vaut mieux voir les variables comme des flèches reliant un nom à un objet. Pour se rendre compte du phénomène on va utiliser la fonction id qui associe à un objet python l’addresse dans la mémoire vive où est stocké l’objet.
>>> x = 12345676
>>> x
12345676
>>> y = x
>>> y
12345676
>>> z = 12345676
>>> z
12345676
>>> id(x)
139645750075024
>>> id(y)
139645750075024
>>> id(z)
139645750075152On constate que plusieurs variables (x et y) peuvent faire référence au même objet, mais que ce n’est pas possible de deviner lesquelles en utilisant jute la valeur de l’objet car x, y et z ont même valeur mais l’adresse de z est différente.
Le problème est qu’une mutation de l’objet sous jacent à x sera aussi vu depuis y (opération à ne pas confondre à une réaffectation de la variable vers un autre objet obtenue avec =). Les entiers sont heureusement immutables donc pas susceptible à ce bug mais on reviendra sur ces difficultés lorsqu’on abordera les listes.
a et b contenant des entiers sans utiliser de troisième variable. On n’aura juste le droite de faire des assignations à a et b et des opérations arithmétiques.Pour les conventions sur les noms on regardera
>>> help("IDENTIFIERS")Et pour une description complète de l’affectation
>>> help("ASSIGNMENT")Ou aller regarder la documentation en ligne ici et là. On a fourni la version française mais on peut changer via le menu déroulant en haut à gauche.
>>> restant0 = 1
>>> decimale1 = restant0 * 10 // 21
>>> restant1 = restant0 * 10 % 21
>>> decimale2 = restant1 * 10 // 21
>>> restant2 = restant1 * 10 % 21
>>> decimale3 = restant2 * 10 // 21
>>> restant3 = restant2 * 10 % 21
>>> decimale4 = restant3 * 10 // 21
>>> restant4 = restant3 * 10 % 21
>>> decimale1
0
>>> decimale2
4
>>> decimale3
7
>>> decimale4
6>>> a = 12
>>> a
12
>>> b = 21
>>> b
21
>>> a = a + b
>>> b = a - b
>>> a = a - b
>>> a
21
>>> b
12