a = 4
strictement parlant, a n'est pas une variable comme on l'entends au même titre qu'avec un langage comme C ou C++ et l’opérateur d'assignation (=), lui, et bien, vous allez voir. Je vais couvrir ici de l'information supplémentaire, pour ceux qui aiment comprendre dans le détail. Même si vous débutez a peine, c'est une bonne idée de lire cet article et de s'y referer dans le futur, quand on a une meilleure compréhension du langage.
Le modèle C
En C, on assigne la valeur 4 a un entier a, que l'on définit grâce au mot clé int
int a = 4;
int b = 17;
Regardons ce qui se passe en arrière plan, avec une représentation de la mémoire. Prenons un exemple simple, avec 4 espaces mémoire et ou chaque int prend 1 espace.
espace 1 | espace 2 | espace 3 | espace 4 |
Après avoir assigné a = 4 et b = 17, on se retrouve avec:
espace 1 | espace 2 | espace 3 | espace 4 |
4 | 17 |
La variable a est a l'espace 1, qui contient une valeur de 4. Le compilateur sait que, a chaque fois que l'on utilise la variable a, on parle de l'espace mémoire 1. Faire a = 5 nous donne simplement:
espace 1 | espace 2 | espace 3 | espace 4 |
5 | 17 |
L'espace 2 est utilise par une autre variable (b). De ce fait, il serait impossible de changer notre variable a d'un entier par une chaine de caractères, car l'espace 2, 3, etc n'est pas disponible. De toute façon, C réserve l'espace mémoire pour un int au moment de la compilation et on ne sait jamais l'ordre dans lequel les variables sont en mémoire (chaque compilateur le fait différemment).
Avec Python, pas de problème de ce genre:
Le modèle Python
En Python, quand on déclare a = 4, en fait ce que l'on fait c'est de créer un objet, un entier de valeur 4:
objet: 4 |
Puis le a = lui donne un nom:
objet: 4 |
a |
Si on "assigne" 5 en écrivant a = 5, on crée un autre objet, un entier de valeur 5:
|
|
Puis le a = lui donne un nom, et comme il ne peut y avoir qu'un seul objet avec le même nom, notre objet:4 perd son nom:
|
|
Éventuellement, Python se débarrasse de l'objet sans nom (4) et on se retrouve avec:
objet: 5 |
a |
Et que se passe t'il si on fait b = a ?
objet: 5 |
a b |
Les variables a et b nomment toutes deux l'objet int() de valeur 5.
Cette flexibilité entraine néanmoins une perte de performance par rapport au modèle du langage C, car il faut créer un nouvel objet pour chaque "assignation" (création d'un objet et étiquetage du nom, en fait).
dir()
Il y a une fonction bien utile avec python, c'est dir(). Cela retourne une liste des noms qui sont disponibles. Donc si on déclare a = 4, on y trouvera 'a' dans cette liste. Et si on fait dir(a), alors on peut voir toutes les méthodes qui peuvent être appliquées a cet objet 'a'.
C'est le temps d'essayer quelques trucs avec python en mode interactif:
pi@fdion-rpi ~ $ pythonOn voit bien que python retourne 4, et que a a des methodes du genre __int__ et real, celles de int(). Continuons:
Python 2.7.3rc2 (default, May 6 2012, 20:02:25)
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__']
>>> a = 4
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a']
>>> b = 17
>>> dir()
['__builtins__', '__doc__', '__name__', '__package__', 'a', 'b']
>>> dir(a)
['__abs__', '__add__', '__and__', '__class__', '__cmp__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__float__', '__floordiv__', '__format__', '__getattribute__', '__getnewargs__', '__hash__', '__hex__', '__index__', '__init__', '__int__', '__invert__', '__long__', '__lshift__', '__mod__', '__mul__', '__neg__', '__new__', '__nonzero__', '__oct__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'imag', 'numerator', 'real']
>>> a
4
>>> a = 5
>>> a
5
Entre la première et deuxième ligne, python a du travailler dur a créer un nouvel objet et lui a donné le nom a. Notre ancien a (4) lui, il est dans les vapes (et python s’apprête a faire le ménage et a le virer). Mais comme c'est pas évident de voir que c'est ce qui ce passe, on va utiliser une chaine de caractère, cette fois:
>>> a = "wow"
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']
>>>
C'est tres clair que a n'est pas le meme objet, car on ne retrouve plus __int__ ni real, par exemple. On y retrouve les methodes d'un objet str().
Conclusion
La ligne de code Python a = 4 represente donc un objet int() de valeur 4 qui a pour nom a.
On va donc clore cette petite (!) parenthèse la dessus, et on se revoit pour le prochain tutoriel.
No comments:
Post a Comment