Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

python je patauge mais je me soigne.

5 réponses
Avatar
laurent FRANCOIS
Voici un petit morceau de code:
***********
>>>data = ('a','b')
>>>class Test(object):
def __init__(self, data):
self.data = data
def modif(self):
self.data = 'newdata'

>>>ins = Test(data)
********

>>>ins.data
('a', 'b')

>>>ins.modif()

>>>data
('a', 'b')

>>>ins.data
'newdata'


data qui est une variable global n'est pas modifiée. C'est ce à quoi je
m'attendais.

Mais si je code:

*****
>>>class Test(object):
def __init__(self, data, key):
self.data = data
self.key = key
def modif(self):
self.data[self.key] = 'newname'


>>>data ={'key1':'vlaue1','key2':'value2'}

>>>pat = Test(data,'key1')

>>>pat.modif()

>>>pat.key
'key1'

>>>pat.data
{'key2': 'value2', 'key1': 'newname'}

>>>data
{'key2': 'value2', 'key1': 'newname'}

*****

Là je ne comprends pas pourquoi la variable global data est modifiée. Ce
code n'est pas tres différent du premier.

Est-ce que l'on peut m'expliquer ce que je n'ai pas compris?


Merci et Bonne Année

5 réponses

Avatar
Bruno Desthuilliers
laurent FRANCOIS a écrit :
Voici un petit morceau de code:
***********
>>>data = ('a','b')
>>>class Test(object):
def __init__(self, data):
self.data = data
def modif(self):
self.data = 'newdata'

>>>ins = Test(data)
********

>>>ins.data
('a', 'b')

>>>ins.modif()

>>>data
('a', 'b')

>>>ins.data
'newdata'


data qui est une variable global n'est pas modifiée. C'est ce à quoi je
m'attendais.

Mais si je code:

*****
>>>class Test(object):
def __init__(self, data, key):
self.data = data
self.key = key
def modif(self):
self.data[self.key] = 'newname'


>>>data ={'key1':'vlaue1','key2':'value2'}

>>>pat = Test(data,'key1')

>>>pat.modif()

>>>pat.key
'key1'

>>>pat.data
{'key2': 'value2', 'key1': 'newname'}

>>>data
{'key2': 'value2', 'key1': 'newname'}

*****

Là je ne comprends pas pourquoi la variable global data est modifiée.



Parce que pat.data (donc pat.__dict__['data']) et data sont deux
références sur le même objet.

Ce
code n'est pas tres différent du premier.



Si. La difference est que dans le premier cas, Test.modif() réassocie
ins.data à un autre objet - ce qui supprime l'association avec l'objet
global data, alors que dans le second, non - donc pat.data est toujours
une référence sur le même objet que la globale de même nom.

Est-ce que l'on peut m'expliquer ce que je n'ai pas compris?



Contrairement à ce qui se passe dans des langages comme le C, Pascal
etc, les "variables" Python ne sont pas des adresses mémoire "contenant"
une valeur, ce sont des associations entre un nom et une référence sur
un objet. Ton exemple ci-dessus se résume très simplement:

>>> a = [1, 2, 3] # associe le nom 'a' et l'objet [1, 2, 3]
>>> b = a # associe le nom 'b' et l'objet lié au nom 'a'
>>> b is a # les deux noms pointent sur le même objet
True
>>> id(a) # ce qu'on vérifie aussi en comparant les id
3083781324L
>>> id(b)
3083781324L
>>> b.append(4) # modifie l'objet associé à 'b'
>>> b
[1, 2, 3, 4]
>>> a # comme les deux noms pointent sur le même objet:
[1, 2, 3, 4]
>>> b = [5, 6, 7] # réassocie le nom 'b' à l'objet [5,6, 7]
>>> b
[5, 6, 7]
>>> a # ceci ne change rien à la liaison de 'a'
[1, 2, 3, 4]
>>> b is a # les deux noms pointent sur des objets différents
False
>>> id(a) # ce qu'on vérifie en comparant les id
3083781324L
>>> id(b)
3083782860L
>>>


Ne perd pas de vue que la syntaxe "a[x] = y" est un sucre syntaxique
pour "a.__setitem__(x, y)" - ce n'est pas une assignation, c'est un
appel de méthode qui modifie l'objet en place.

D'une manière générale : tout ce que tu peux manipuler en Python est une
référence sur un objet, et l'"assignation" consiste simplement à
associer un nom à une référence sur un objet. Python ne fait jamais de
"copie", sauf si tu le demande très explicitement.

HTH
Avatar
laurent FRANCOIS
Bruno Desthuilliers wrote:


Ne perd pas de vue que la syntaxe "a[x] = y" est un sucre syntaxique
pour "a.__setitem__(x, y)" - ce n'est pas une assignation, c'est un
appel de méthode qui modifie l'objet en place.




D'accord. Ok j'avais pas saisi ce point.
Merci beaucoup.
Avatar
Bruno Desthuilliers
laurent FRANCOIS a écrit :
Bruno Desthuilliers wrote:


Ne perd pas de vue que la syntaxe "a[x] = y" est un sucre syntaxique
pour "a.__setitem__(x, y)" - ce n'est pas une assignation, c'est un
appel de méthode qui modifie l'objet en place.






J'ajoute par souci d'exhaustivité qu'il en va de même pour "obj.x = y"
qui est un sucre syntaxique pour "obj.__setattr__('x', y).
Avatar
laurent FRANCOIS
Bruno Desthuilliers wrote:
laurent FRANCOIS a écrit :
Bruno Desthuilliers wrote:


Ne perd pas de vue que la syntaxe "a[x] = y" est un sucre syntaxique
pour "a.__setitem__(x, y)" - ce n'est pas une assignation, c'est un
appel de méthode qui modifie l'objet en place.






J'ajoute par souci d'exhaustivité qu'il en va de même pour "obj.x = y"
qui est un sucre syntaxique pour "obj.__setattr__('x', y).




Justement est-ce que c'est exhaustif?
Ou bien il existe d'autres expressions "quelquechose = y" qui n'est pas
une affectation mais une modification d'un objet en place?

Merci
Avatar
Bruno Desthuilliers
laurent FRANCOIS a écrit :
Bruno Desthuilliers wrote:
laurent FRANCOIS a écrit :
Bruno Desthuilliers wrote:


Ne perd pas de vue que la syntaxe "a[x] = y" est un sucre syntaxique
pour "a.__setitem__(x, y)" - ce n'est pas une assignation, c'est un
appel de méthode qui modifie l'objet en place.






J'ajoute par souci d'exhaustivité qu'il en va de même pour "obj.x = y"
qui est un sucre syntaxique pour "obj.__setattr__('x', y).




Justement est-ce que c'est exhaustif?



Est-ce que tu vois d'autres cas d'utilisation dy symbole "=" ? (hormis
bien sur les compositions de type '+=', '!=', '==' etc).

Ou bien il existe d'autres expressions "quelquechose = y" qui n'est pas
une affectation mais une modification d'un objet en place?



Note que dans les deux cas évoqués ci dessus, la syntaxe n'est pas
"quelquechose = y", mais soit "quelquechose[autrechose] = y" soit
"quelquechose.autrechose = y". Bref, dans les deux cas il y a
explicitement un "autrechose" qui entre en jeu.