Affectation (d'après "Learning Python", de Mark Lutz) Formation Python Affectation (d'après "Learning Python", de Mark Lutz) A revoir : *) pour les débutants, faire l'impasse sur la réutilisation des objets entiers et le "is" (peut-être classer "is" dans les pièges). *) refaire les démos en "animations" *) parler de "shallow copy" et "deep copy".
Questions abordées Qu'est-ce qu'une "variable" ? Qu'est-ce qu'une valeur ? Qu'est-ce qu'un type ? Comment est gérée la mémoire ? Comment sont passés les arguments de fonction ? Comment se passe une copie ? Comment est évaluée l'égalité ? .
Variables et objets a = 3 a = 'hello' a = 1.23 a 3 a 3 hello a 3 hello Pour les programmeurs C++, on peut voir les noms de python comme des pointeurs no typés (void *), mais qui sont automatiquement déréférencés quand on les utilise. Ce sont les objets qui sont typés, et en réalité chaque objet est précédé en mémoire de deux entêtes : son type son compteur de références a 3 hello 1.23
Partage d'objets a = 3 b = a a = 'hello' a = a+2 c = 3 a 3 b a 3 b 5
Modification d'un élément (1/2) l2 = l1 l1[0] = 5 l1 [0,1,2] l2 2 3 4 l1 [0,1,2] l2 5 3 4
Modification d'un élément (2/2) [0,1,2] l1 = [2,3,4] l2 = l1[:] l2[1] = 6 l1 2 3 4 l2 [0,1,2] Pour copier un dictionnaire, qui ne se "slice" pas : D.copy(). Pour copier n'importe quoi, de façon superficielle ou profonde : > import copy > X = copy.copy(Y) > X = copy.deepcopy(Y) [0,1,2] l1 2 3 4 l2 [0,1,2] 6
Egalité et identité (1/4) l2 = l1 l1==l2 True l1 is l2 l1 [0,1,2] l2 2 3 4
Egalité et identité (2/4) l1==l2 True l1 is l2 False l1 [0,1,2] 2 3 4 l2 [0,1,2]
Egalité et identité (3/4) x = 42 y = 42 x==y True x is y l1 42 l2 Attention, "is" peut-être beaucoup plus rapide que "==" dans certaines circonstances, mais c'est un faux ami parce qu'il est influencé par le mécanisme de cache interne de Python.
Egalité et identité (4/4) x = 42.5 y = 42.5 x==y True x is y False l1 42.5 l2 42.5 Attention, "is" peut-être beaucoup plus rapide que "==" dans certaines circonstances, mais c'est un faux ami parce qu'il est influencé par le mécanisme de cache interne de Python.
Passage d'arguments def changer(a,b): … a = 2 … b[0] = 'hello' … x = 1 y = [1,2] changer(x,y) x,y (1,['hello',2]) x 1 2 a y [0,1] Les arguments d'une fonction sont passés par affectation à des variables locales à la fonction. Assigner un nouvel objet à l'une de ces variables n'affecte pas l'appelant. Modifier un élément d'une collection mutable peut affecter l'appelant. b 'hello'
Affectation dans une fonction x = 88 y = [ 1, 2 ] def func(): … x = 99 … y[0] = 0 func() x, y ( 88, [0,2] ) Dans une fonction, toute affectation à une variable qui n'est pas un de ses arguments crée une variable locale, sauf s'il s'agit d'un élément d'une collection mutable. Toute affectation dans une fonction crée une variable locale, sauf s'il s'agit d'un élément d'une collection mutable.
Résumé Les types sont attachés aux objets, pas aux variables. Chaque objet est rendu au système quand il n'est plus désigné par aucune variable. La modification d'un élément de collection affecte toutes les variables désignant cette collection. Le passage des arguments d'une fonction se fait par affectation à des variables locales. Les affectations au sein des fonctions créent des variables locales. A la différence de C++, qui distingue variables ordinaires, références, pointeurs. passage d'arguments par valeur, référence, pointeur.
Quiz (1/5) Quelle est la valeur finale retournée par a ? a = "hello" b = a b = "world" a a hello "hello" b world .
Quiz (2/5) Quelle est la valeur finale retournée par a ? a = [ "hello" ] b = a b[0] = "world" a [ "world" ] world . a [0] b hello
Quiz (3/5) Quelle est la valeur finale retournée par a ? a = [ "hello" ] b = a[:] b[0] = "world" a a [0] [ "hello" ] . hello b [0] world
Quiz (4/5) Quelle est la valeur finale retournée par a ? def f(x): … x = "world" a = "hello" f(a) a . a hello x world "hello"
Quiz (5/5) Quelle est la valeur finale retournée par a ? def f(x): … x[0] = "world" a = [ "hello" ] f(a) a world a [0] . x hello [ "world" ]