IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

Des variables (malheureusement) synchronisées


Sujet :

Python

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2022
    Messages : 22
    Points : 21
    Points
    21
    Par défaut Des variables (malheureusement) synchronisées
    Bonjour ou bonsoir,

    Je suis face à un problème depuis bientôt quelques heures et je ne trouve aucune solution de par mes nombreux tests ou sur google.
    J'utilise donc une liste1 en tant qu'attribut privé dans une dataclass. J'ai d'un autre côté une méthode qui contient une liste2, une copie de l'attribut privé liste1 (j'ai donc "liste2 = self.liste1.copy()" ) pour me permettre de la modifier tout en gardant la liste d'origine.
    Or, je me retrouve toujours avec le même problème qui est qu'en modifiant ma liste2, les modifiations s'effectuent également sur la liste1 alors que je ne la redéfini pas pour être égale à la liste2. Je pensais pourtant que la fonction ".copy()" était là pour palier à ce problème.

    Malgrès de nombreux essais je ne réussi pas à reproduire ce problème de manière simplifiée (et je ne pense pas non plus vous envoyer des centaines de lignes de code pour ça T-T).
    Je me demandais donc si un détail m'échapait (à propos de ".copy()" ou peut-être des dataclasses) ou si quelqu'un aurait une idée de la source de mon problème (même si je suis conscient que sans un code précis sous les yeux la tâche n'est vraiment pas évidente...)

    Désolé et merci d'avance pour vos réponses

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par Zarkoro Voir le message
    J'utilise donc une liste1 en tant qu'attribut privé dans une dataclass. J'ai d'un autre côté une méthode qui contient une liste2, une copie de l'attribut privé liste1 (j'ai donc "liste2 = self.liste1.copy()" ) pour me permettre de la modifier tout en gardant la liste d'origine.
    Tu peux aussi écrire liste2=list(self.liste1) ou liste2=self.liste1[:]. Toutefois en écrivant self.liste1 cela fait de "liste1" un attribut public et non privé (ce qui n'a pour ton souci aucune importance mais c'est pour rectifier le détail).

    Citation Envoyé par Zarkoro Voir le message
    Or, je me retrouve toujours avec le même problème qui est qu'en modifiant ma liste2, les modifiations s'effectuent également sur la liste1 alors que je ne la redéfini pas pour être égale à la liste2. Je pensais pourtant que la fonction ".copy()" était là pour palier à ce problème.
    Oui, c'est en effet bien le cas. Son but est de créer une copie distincte de la liste d'origine.
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> liste1=list(range(10))
    >>> liste2=liste1.copy()
    >>> liste2.append("toto")
    >>> liste2
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'toto']
    >>> liste1
    [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    >>>

    Citation Envoyé par Zarkoro Voir le message
    Malgrès de nombreux essais je ne réussi pas à reproduire ce problème de manière simplifiée
    Alors c'est que le problème vient d'autre part que depuis la copie. Tu peux d'ailleurs vérifier que les deux listes sont bien différentes via assert id(self.liste1) != id(liste2) juste après le copy(). Ensuite tu remets la même instruction juste avant l'endroit où se produit le problème. Si elles sont bien différentes après le copy() (et elles le sont) le premier assert passera sans souci. Et si elles ne sont plus différentes là où tu détectes le souci (ce qui semble être le cas) le second assert te le prouvera en renvoyant une exception AssertionError.

    Citation Envoyé par Zarkoro Voir le message
    même si je suis conscient que sans un code précis sous les yeux la tâche n'est vraiment pas évidente...)
    Eh oui. Mis à part ces suggestions, sans code reproduisant le souci...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Expert éminent
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    3 824
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 824
    Points : 7 120
    Points
    7 120
    Par défaut
    Bonsoir,

    @zarkoro,

    Si je ne me trompe pas, vous oubliez de spécifier le plus important qui est de connaître le type des éléments dans votre liste à copier.

    Avez-vous vérifié si les éléments contenus dans votre liste sont des types immuables (comme les entiers, flottants, chaînes de caractères) ou des objets mutables (comme des listes, dictionnaires, ou instances de classes personnalisées) ? La méthode .copy() effectue une copie superficielle, ce qui signifie que pour des objets mutables contenus dans votre liste, seule la référence à ces objets est copiée et non les objets eux-mêmes. Cela pourrait-il expliquer le comportement que vous observez ?

    Pour éviter cela, vous auriez besoin d'une copie profonde (deepcopy).
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 690
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 690
    Points : 30 986
    Points
    30 986
    Billets dans le blog
    1
    Par défaut
    Démonstration de la remarque de fred1599 (à laquelle effectivement je n'avais pas pensé)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> liste1=[1, 3, [2, 4, 6]]
    >>> liste2=liste1.copy()
    >>> liste2.append("toto")
    >>> liste2
    [1, 3, [2, 4, 6], 'toto']
    >>> liste1
    [1, 3, [2, 4, 6]]
    Ok jusque là tout va bien. Mais continuons...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> liste2[2].append("titi")
    >>> liste2
    [1, 3, [2, 4, 6, 'titi'], 'toto']
    >>> liste1
    [1, 3, [2, 4, 6, 'titi']]
    >>>
    La copie d'une liste copie individuellement tous ses éléments internes, mais ça ne marche que si ces éléments sont des éléments immuables (int, str, tuple). Si un de ces éléments est mutable (list, set, dict, objet) cet élément est lui-même simplement référencé lors de la copie. Bref la copie ne se fait qu'au niveau de base de la liste.

    Le module "copy" (module à importer) possède une méthode "deepcopy()" qui, elle, fait le travail en entier. Elle va au plus profond et chaque élément mutable est cette-fois réellement copié et non simplement re-référencé.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2022
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2022
    Messages : 22
    Points : 21
    Points
    21
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    Avez-vous vérifié si les éléments contenus dans votre liste sont des types immuables (comme les entiers, flottants, chaînes de caractères) ou des objets mutables (comme des listes, dictionnaires, ou instances de classes personnalisées) ? La méthode .copy() effectue une copie superficielle, ce qui signifie que pour des objets mutables contenus dans votre liste, seule la référence à ces objets est copiée et non les objets eux-mêmes. Cela pourrait-il expliquer le comportement que vous observez ?
    En effet vous avez très probablement raison ! Mes listes contiennent elle-même des listes ce qui a dû poser problème. J'étais innocemment parti du principe que la fonction copy() 'désynchronisait' d'elle-même chaque composant de la liste.

    Citation Envoyé par Sve@r Voir le message
    Le module "copy" (module à importer) possède une méthode "deepcopy()" qui, elle, fait le travail en entier. Elle va au plus profond et chaque élément mutable est cette-fois réellement copié et non simplement re-référencé.
    Merci pour votre solution et vos explications à vous deux ! Ça me rassure un peu de ne pas avoir à aller checker chaque ligne du programme... ^^"""

    L'erreur venant bien de là, mon problème est résolu

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment synchroniser des variables
    Par jbaudens dans le forum Langage
    Réponses: 2
    Dernier message: 26/09/2007, 10h55
  2. Réponses: 4
    Dernier message: 15/12/2002, 04h19
  3. Gestion des variables - mémoire ?
    Par RIVOLLET dans le forum Langage
    Réponses: 4
    Dernier message: 26/10/2002, 12h44
  4. [VB6] [Fichier] Enregistrer des variables de structure
    Par de.bo dans le forum VB 6 et antérieur
    Réponses: 4
    Dernier message: 07/10/2002, 11h09
  5. Réponses: 4
    Dernier message: 18/07/2002, 13h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo