Sve@r | luclechanceux a écrit :
Bonjour tout le monde,
Voici mon problème : J'ai un template de dictionnaire type Code :
- asset = { "entrée1" : "blabla", "entrée2" : "plop",... ,"entréeN" : a,.... }
|
ensuite je parse
un dossier pour récupérer des identifiants et affecter ce template à un dictionnaire bcp plus gros (composé donc de pleins d'unité type asset) que j'enverrai par la suite dans un json. Voila le contexte.
Le souci ici réside dans l'affectation des différentes entrées. Je m'explique imaginons que j'ai un identifiant X avec un paramètre entréeN
à 3. Je procède comme suit, Code :
- asset["entréeN"] = 3
|
puis je fais Code :
- dictionnaireGlobal[X] = asset
|
puis je remets asset["entréeN"] à sa valeur initiale. Problème dictionnaireGlobal[X]["entréeN"] ne sera pas la valeur 3 mais à la valeur initiale o_O!!!! et bien sur si je ne remets pas
asset["entréeN"] à sa valeur initiale toutes les asset["entréeN"] qui apparaissent dans dictionnaireGlobal sont à 3!!
Au final je souhaiterai donc pouvoir modifier et sauvegarder des données suivant un template défini (sous forme d'un dictionnaire) sans que
cela n'affecte les précédentes sauvegardes. Je me comprends mais je ne sais pas si c'est suffisamment clair... Je flaire un problème de pointeur/valeur
mais si je ne m'abuse la notion de pointeur en python n'est pas trop répandue non?
Et la j'avoue mon ignorance, ou alors je suis passé à coté de qqc d'évident auquel cas je vous prie d'excuser le dérangement.
|
Salut
Les pointeurs en Python sont très répandus... mais aussi très cachés. Toutefois, toute copie d'objet un tant soi peu complexe ne se fait que par pointeur
Exemple
Code :
>>> a=range(5) >>> a [0, 1, 2, 3, 4] >>> b=a >>> a[0]="toto" >>> b ['toto', 1, 2, 3, 4]
|
Alors tu as bien trouvé le truc => passer par le module "copy" qui copie les objets par contenu et non par pointeur. Cependant, la méthode copy.copy s'arrête au premier niveau et le problème persiste si les objets copiés possèdent eux-mêmes des objets complexes
Exemple
Code :
>>> import copy >>> a={"key1" : 10, "key2" : {"base" : range(5)}} >>> b=copy.copy(a) >>> a {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10} >>> b {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10} >>> a["key1"]=5 >>> a {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 5} >>> b {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10} >>> a["key2"]["base"]="toto" >>> a {'key2': {'base': 'toto'}, 'key1': 5} >>> b {'key2': {'base': 'toto'}, 'key1': 10}
|
Comme tu le vois, la copie s'est arrêtée au premier niveau "key1". Le second objet "key2" a été, lui, copié par adresse.
Si tu veux une copie vraiment séparée quelle que soit la profondeur des objets imbriqués, il te faut utiliser "copy.deepcopy"
Code :
>>> a={"key1" : 10, "key2" : {"base" : range(5)}} >>> a {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10} >>> b=copy.deepcopy(a) >>> b {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10} >>> a["key1"]=5 >>> a["key2"]["base"]="toto" >>> a {'key2': {'base': 'toto'}, 'key1': 5} >>> b {'key2': {'base': [0, 1, 2, 3, 4]}, 'key1': 10}
|
Message édité par Sve@r le 19-11-2011 à 15:06:33
|