Code:
1
2
3
4
5
6
7 >>> var = [5] >>> def setVar(n): ... var[0] = n ... >>> setVar(2) >>> var [2]
Version imprimable
Code:
1
2
3
4
5
6
7 >>> var = [5] >>> def setVar(n): ... var[0] = n ... >>> setVar(2) >>> var [2]
Merci Fred. J'ai bien compris maintenant ce mécanisme concernant les espaces de noms et la portée des variables.
Sur mon dernier message je demandais juste pourquoi on voit écrit sur certains livres que "les variables définies à l'extérieur d'une fonction ne peuvent pas être modifiés par la fonction". En fait ceci est faux. Ou du moins incomplet. Il faut dire : "une fonction ne peut modifier, par affectation, la valeur d'une variable extérieure à son espace local."
Je m'intéressais plutôt aux classes et instances, mais le mécanisme est similaire.
Salut,
Le tuto du Swinnen, dans le chapitre que vous citiez au début, racontait cela en écrivant:
Et c'est ce qu'on a essaye de vous faire partager dans les différents posts.Citation:
Vous avez appris également que les instructions se trouvant à l'intérieur d'une fonction peuvent accéder aux variables définies au niveau principal, mais en consultation seulement : elles peuvent utiliser les valeurs de ces variables, mais pas les modifier (à moins de faire appel à l'instruction global).
- W
J'interviens pour corriger ceci:
Non. Simplement quand tu écris obj1.var1 (un accès en lecture), Python regarde d'abord s'il existe un attribut d'instance var1 dans obj1. Si ce n'est pas le cas, il regarde alors dans la classe de obj1 s'il n'y a pas un attribut de classe nommé var1, et retourne alors sa valeur.Citation:
A la lumière de ce que m'a expliqué chticricri plus haut, voici comment je vois les choses :
L'objet obj1 se voit automatiquement attribuer une copie de la variable de classe var1 lors de son instanciation. Cette copie est une variable d'instance de obj1 et s'appelle aussi var1, mais elle n'est pas dans le même espace de noms. On peut donc théoriquement modifier la variable d'instance var1, sans que cela ne modifie la variable de classe var1.
Par contre, quand tu écris obj1.var1 = ..., il crée (ou modifie) un attribut d'instance var1 dans obj1, sans même regarder s'il y a un attribut de classe du même nom. Et les futurs accès à obj1.var1 concerneront donc l'attribut d'instance, comme expliqué ci-dessus.
L'attribut de classe n'est pas copié automatiquement en attribut d'instance, ce dernier est créé par une assignation (comme n'importe quelle variable en Python).