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 :

Remplissage et parcours de liste d'objets


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau candidat au Club
    Homme Profil pro
    Analyse système
    Inscrit en
    Novembre 2021
    Messages
    1
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aveyron (Midi Pyrénées)

    Informations professionnelles :
    Activité : Analyse système

    Informations forums :
    Inscription : Novembre 2021
    Messages : 1
    Par défaut Remplissage et parcours de liste d'objets
    Bonjour à tous,

    Je débute en python et j'ai une question concernant le stockage de différentes instances de classes.
    J'ai écrit la fonction suivante qui remplit des attributs d'une instance de la classe Piezometer (peu importe ce que cela représente), sur la base de la lecture de lignes d'un fichier d'un fichier texte (je remplis les attributs d'une instance par ligne lue).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    def ReadAllPiezometerAttributes(FilePath):
     
        ListPiez =  []
        cpt = 0
     
        with open(FilePath,'r') as fileAtt:
            data = fileAtt.readline()
     
            while data:
                info = data.split()
                ListPiez.append(Piezometer(info[3],info[0],info[8],info[7],info[6],info[1],info[10],info[11],info[9])) 
                print(ListPiez[cpt])
                data = fileAtt.readline()
                cpt+=1
     
            print("{} piezos have been stored.".format(len(ListPiez)))
     
        for i in range(len(ListPiez)):
            print(ListPiez[i])
     
        return ListPiez
    Définition de la classe associée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    class Piezometer:
        def __init__(self, nom, ids, id_mabs, id_layer, id_mintern, bss, x, y, layername):
            self._name = nom                
            self._id = ids                       
            self._id_mabs = id_mabs        
            self._id_layer = id_layer      
            self._id_mintern = id_mintern   
            self._bss = bss                 
            self._x = x              
            self._y = y                  
            self._layername = layername   
            self._obs_timeserie = {}        
            self._sim_timeserie = {}        
     
        @classmethod
        def __str__(self):
            return "Piezo id : {}, Name : {} ({}) - Model location : ABS {} - ({},{})".format(self._id, self._name,self._bss,self._id_mabs,self._id_layer,self._id_mintern)
    Mon problème est résumé par l'output obtenu, qui est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    Piezo id : 1, Name : Gumery (02606X1013-S1) - Model location : ABS 6044 - (0,6043)
    Piezo id : 2, Name : Noyen-Sur-Seine (02606X0125-PM3) - Model location : ABS 2737 - (0,2736)
    Piezo id : 3, Name : Noyen-Sur-Seine (02606X0112-G5) - Model location : ABS 2541 - (0,2540)
    Piezo id : 4, Name : Mouy-Sur-Seine (02605X0062-M4) - Model location : ABS 160 - (0,159)
    Piezo id : 5, Name : Rheges (02621X0009-S1) - Model location : ABS 298 - (0,297)
    Piezo id : 6, Name : Rheges (02621X0085-PZ) - Model location : ABS 298 - (0,297)
    Piezo id : 7, Name : Nogent-Sur-Aube (02628X0005-P1) - Model location : ABS 241 - (0,240)
    Piezo id : 8, Name : Chalons-En-Champagne (01891X0047-PZ1) - Model location : ABS 4746 - (0,4745)
    Piezo id : 9, Name : Asfeld (01082X0015-P-SUD) - Model location : ABS 2923 - (0,2922)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    10 piezos have been stored.
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    Piezo id : 10, Name : Bucy-Le-Loing (01067X0362-BL7) - Model location : ABS 1806 - (0,1805)
    J'ai bien du mal à comprendre pourquoi le second parcours de la liste, en fin de fonction, (et a fortiori, la liste retournée par la fonction) ne contient que la dernière instance dupliquée partout ?!?! (alors que la liste semble correctement constituée (cf. le print en cours de boucle).

    J'espère que l'exemple est assez clair.
    Merci beaucoup par avance pour votre aide,

    oblivion0-dev

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Lorsque vous postez du code, il faudrait qu'il fonctionne.
    Ici:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class Piezometer:
         ...      
        @classmethod
        def __str__(self):
            return "Piezo id : {}, Name : {} ({}) - Model location : ABS {} - ({},{})".format(self._id, self._name,self._bss,self._id_mabs,self._id_layer,self._id_mintern)
    va planter à cause du classmethod qui induit l'accès a des attributs de classe inexistants.

    Et qu'il soit suffisant à reproduire le problème (pas des petits bouts à assembler comme le vendeur de meubles célèbre).

    Si on n'arrive pas, comme vous, à trouver l'erreur juste en relisant le code...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 307
    Par défaut
    Salut,

    C'est ton décorateur qui te joue ce tour.

    Une classmethod reçoit la classe en premier argument et non l'instance.
    Tu aurais d'ailleurs dû écrire __print__(cls), ça a l'air d'un détail mais un détail qui alerte sur le type de l'argument.

    Personnellement, j'utilise def __repr__(self) pour ça, sans décorateur.

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par VinsS Voir le message
    C'est ton décorateur qui te joue ce tour.
    Pas que, sinon ça n'afficherait pas correctement la liste la première fois.
    Ça dit juste que le code posté n'est pas cohérent avec l'histoire (si ça plante a tous les coups, ça n'affiche rien!).

    Et que si l'histoire est "une liste avec initialisée avec 5 objets différents devient 5 objets identiques" sans montrer où cette liste est modifiée... demande plus de code.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par oblivion0-dev Voir le message
    J'ai bien du mal à comprendre pourquoi le second parcours de la liste, en fin de fonction, (et a fortiori, la liste retournée par la fonction) ne contient que la dernière instance dupliquée partout ?!?! (alors que la liste semble correctement constituée (cf. le print en cours de boucle).
    Désolé mais ton code n'est pas fonctionnel. Comme déjà dit par wiztricks, la méthode __str__() (surcharge de str()) n'est pas une méthode de classe et la déclarer ainsi prooque une exception "AttributeError" puisque ne récupérant pas une instance, la méthode ne trouve pas d'attribut "_name".

    Et en tentant de reproduire ton problème en corrigeant l'erreur, ton problème tel que décrit ne se produit pas
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    #!/usr/bin/env python3
    # coding: utf-8
     
    class Piezometer:
    	def __init__(self, nom):
    		self._name = nom				
     
    	def __str__(self):
    		return "Piezo Name : {}".format(self._name)
    # class Piezometer
     
    def ReadAllPiezometerAttributes():
    	ListPiez=[]
     
    	for i in range(5):
    		ListPiez.append(Piezometer("i=%d" % i))
     		print("{} piezos have been stored.".format(len(ListPiez)))
    	# for
     
    	for i in range(len(ListPiez)):
    		print(ListPiez[i], hex(id(ListPiez[i])))
     
    	return ListPiez
    # ReadAllPiezometerAttributes()
     
    piezo=ReadAllPiezometerAttributes()
    print("ok")
    for p in piezo: print(p, hex(id(p)))

    Résultat
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    1 piezos have been stored.
    2 piezos have been stored.
    3 piezos have been stored.
    4 piezos have been stored.
    5 piezos have been stored.
    Piezo Name : i=0 0x7f398cd11ac8
    Piezo Name : i=1 0x7f398cc99278
    Piezo Name : i=2 0x7f398cc99390
    Piezo Name : i=3 0x7f398cc99400
    Piezo Name : i=4 0x7f398cc99470
    ok
    Piezo Name : i=0 0x7f398cd11ac8
    Piezo Name : i=1 0x7f398cc99278
    Piezo Name : i=2 0x7f398cc99390
    Piezo Name : i=3 0x7f398cc99400
    Piezo Name : i=4 0x7f398cc99470
    Les identifiants étant bien tous différents, j'ai bien 5 objets distincts dans ma liste résultant de la fonction

    Citation Envoyé par VinsS Voir le message
    Personnellement, j'utilise def __repr__(self) pour ça, sans décorateur.
    Cette méthode, bien que ressemblante fortement à __str__ (d'autant plus qu'elle sera utilisée en subsitution à cette dernière si celle-ci n'est pas présente quand elle est invoquée), n'a quand-même pas le même but...
    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]

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Pour reproduire votre problème, on ajoute @classmethod à __init__.
    Ce qui va faire "fonctionner" le classmethod du __str__.

    Dans ce cas, on modifiera des attributs de classe et seules les dernières valeurs entrées seront prises en compte.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    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 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Pour reproduire votre problème, on ajoute @classmethod à __init__.
    Ce qui va faire "fonctionner" le classmethod du __str__.

    Dans ce cas, on modifiera des attributs de classe et seules les dernières valeurs entrées seront prises en compte.
    Ah oui, c'est bien vu

    On peut remarquer en plus (en appliquant ton idée à mon exemple) qu'effectivement on a 5 fois le même nom mais on a quand-même 5 objets distincts (id tous différents). Donc 5 objets distincts avec tous le même attribut de classe...
    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]

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Ah oui, c'est bien vu
    Pas facile d'imaginer la créativité des débutants pour fabriquer des problèmes!

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 10
    Dernier message: 23/04/2019, 23h19
  2. Tri d'une liste d'objet CObList
    Par cjacquel dans le forum MFC
    Réponses: 1
    Dernier message: 13/07/2005, 13h50
  3. [MFC] Retourner une liste d'objets
    Par 1cado dans le forum MFC
    Réponses: 10
    Dernier message: 28/07/2003, 12h11
  4. [Kylix] Composant - Liste d'objet
    Par Metal3d dans le forum EDI
    Réponses: 1
    Dernier message: 13/12/2002, 22h17
  5. liste d'objets
    Par Pierrot dans le forum Langage
    Réponses: 2
    Dernier message: 27/09/2002, 09h56

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