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 :

Lister les instances d'une classe


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut [Résolu] Lister les instances d'une classe
    Bonjour.

    Bon, je suis tout nouveau en Python (une semaine) et en pleine lecture des bouquins de W. J. Chun (au coeur de Python en 2 volumes.

    Il me semble qu'on peut écrire ça (code en dessous) par contre je ne sais, ni si c'est pythonique comme vous dites, ni s'il y a des contres indications vu le peux de connaissances de python que j'ai.

    Le code me permet bien d'acceder à mes instances des objets, mc2, mc2bis et mc4 par contre il ne gere pas le fait que mc2 et mc2bis sont des alias (il faudrait rajouter des choses)

    (Il y a aussi un test pour tester le type de classe au milieu qui doit pouvoir être plus jolie, ainsi que quelques print qui trainent).

    Comme se sont mes débuts, si des choses ne sont pas ou pas assez correcte vous pouvez le dire (je sais qu'il y a l'affectation des valeurs par défaut aussi dans l'appel d'une méthode, mais c'était des tests).

    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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    #-*- coding: utf-8 -*-
    '''
    Created on 24 août 2009
     
    @author: Pierre
    '''
     
    import sys
    import psyco
    from inspect import currentframe
     
    class C1(object):
        def m1(self):
            print "Ici C1m1"
     
    class C2(C1):
        def __init__(self):
            self.c2val1 = 8
            self.c2val2 = 'Bonjour'
        def m1(self):
            print "Ici C2m1"
            C1.m1(self)
     
    if __name__ == '__main__' :
        print 'Main ici debut'
        mc1 = C1()
        mc1.m1()
        mc2 = C2()
        mc2.m1()
        mc4 = C2()
        mc4.c2val1 = 19
        mc4.c2val2 = 'Au revoir'
        mc2bis = mc2
     
        frame = currentframe()
        for n_var in frame.f_locals.keys():
            # Dessous pas beau, il doit y avoir un autre moyen
            s = str(type(frame.f_locals[n_var]))
            if s.find('__main__.C2') >= 0 :
                lobj = frame.f_locals[n_var]
                print "*********************************************************************************************"
                print n_var
                print lobj.c2val1
                print lobj.c2val2
                print "*********************************************************************************************"

  2. #2
    Membre habitué
    Inscrit en
    Mars 2003
    Messages
    127
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Mars 2003
    Messages : 127
    Points : 149
    Points
    149
    Par défaut
    ça c'est plus jolie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        for key,item in globals().items():
            if isinstance(item,C2):
                    print key
                    for item in item.__dict__.values():
                            print item

  3. #3
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    oui en plus j'avais essayé de passer effectivement par global() ou local() mais je n'avais pas réussi a le faire fonctionner et je vois l'erreur

    j'avais écrit un truc du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        for n_var in locals():
            ...
            if test C2... :  
                print n_var.c2val1
                print n_var.c2val2
    et erreur sur le n_var.c2val1 car en fait mon n_var est de type de la key du dictionnaire, je pensais que l'iterateur était le tuple

    en mettant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        for n_var in locals():
            obj = locals()[n_var]
            ...
            if test C2... :  
                print obj.c2val1
                print obj.c2val2
    ca fonctionne mieux ...
    sauf si on ajoute des vars (on a le message dictionnaire modifié) on est alors obligé de passer par une variable intermediaire et un deepcopy


    Ce que je ne comprend pas ??????
    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
        print "_________Passe____________________________"
        for n_var, obj in locals().items():
            autre2 = "rr"
            print "OK malgre l'affectation"
            if isinstance(obj, C2) :  
                print 'C2'
                print obj.c2val1
     
        print "_________Ne passe pas____________________________"
        for n_var in locals():
            autre1 = "rr"
            print "Erreur dictionnaire changé"
            obj = locals()[n_var]
            if isinstance(obj, C2) :  
                print 'C2'
                print obj.c2val1
    Pourquoi la premier boucle passe alors que pour la seconde on a "dictionary changed size during iteration" ce qui est compréhensible mais pourquoi on n'a pas le message sur la première (ni d'ailleurs sur la boucle de Tyrus.

    (Le isinstance(obj, C2) est effectivement bien plus jolie)

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    bonjour,

    attention tout de même au isinstance, c'est un peu comme la roue de secours elle est là pour dépanner mais il ne faut pas faire 500km avec

    http://www.canonical.org/~kragen/isinstance/

    pour garder une trace des instances crées par tes classes, je te conseille plutôt quelque chose comme ceci:

    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
    23
    import weakref
    class A(object):
        instances = weakref.WeakKeyDictionary()
        def __new__(self,*args,**kwargs):
            _new = object.__new__(self)
            A.instances[_new] = None
            return _new
        def __init__(self,name):
            self.name = name
    a1 = A("premiere")
    a2 = A("seconde")
    for instance in A.instances:
        print instance.name
    del a1
    for instance in A.instances:
        print instance.name
    a1 = a2
    for instance in A.instances:
        print instance.name
    del instance
    for key,value in globals().items():
        if value in A.instances:
            print key
    qui écrit ça comme sortie:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    premiere
    seconde
    seconde
    seconde
    a1
    a2
    le tout sans avoir eu besoin de isinstance, il y a presque toujours une façon de contourner cette fonction

    cette instruction:

    ne crée pas une nouvelle instance, cela crée juste un nouveau nom, une nouvelle référence.

    attention donc à ne pas confondre instance de la classe et références associées à cette instance

  5. #5
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    M@ j'avais fait une réponse je l'ai perdue.

    Effectivement le isinstance() peut-être génant si C2 descend de C1 et que dans C1 on appelle le isinstance(self, C1) se seras faux si l'appel se fait depuis une instance de C2 alors que le pb n'existe pas avec la solution de kango.

  6. #6
    Membre éprouvé
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Points : 1 066
    Points
    1 066
    Par défaut
    Salut

    Si j'ai bien compris, ton seul souci est de récupérer les objets instanciés pour certaines classes.
    Je me permets de proposer une petite solution, dérivée de ma librairie Aspyct

    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
    23
    24
    25
    26
    27
    28
    29
    In [57]: class Collector(list): # Sous classe de la liste standard
       ....:     def __call__(self, initFunc):
       ....:         def newFunc(instance, *args, **kwargs):
       ....:             initFunc(instance, *args, **kwargs)
       ....:             self.append(instance)
       ....:
       ....:         return newFunc
       ....:
       ....:
     
    In [58]: collector = Collector()
     
    In [59]: class MyLittleClass:
       ....:     @collector # On s'en sert comme décorateur pour __init__
       ....:     def __init__(self):
       ....:         pass
       ....:
       ....:
     
    In [60]: MyLittleClass() # Créer quelques instances
    Out[60]: <__main__.MyLittleClass instance at 0x02BFAB48>
     
    In [61]: MyLittleClass()
    Out[61]: <__main__.MyLittleClass instance at 0x02BFAE90>
     
    In [62]: collector # Toutes les instances sont dispos dans cette liste
    Out[62]:
    [<__main__.MyLittleClass instance at 0x02BFAB48>,
     <__main__.MyLittleClass instance at 0x02BFAE90>]
    Et pour chaque classe que tu veux suivre, tu rajoutes le décorateur.
    Note: si tu fais de l'héritage, tu peux te permettre de mettre le décorateur seulement sur la superclasse.

    Attention, pour ce code, on garde des références des instances dans une liste. Ca peut poser problème si tu veux que les instances soient automatiquement détruites par le GC (garbage collector). Tu peux éventuellement te servir des weakrefs pour pallier à ce problème.

    Enfin, si tu es intéressé par plus de puissance, jette un oeuil à ma librairie, et plus précisément Aspyct.utils.Queryable. http://www.aspyct.org

  7. #7
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 4
    Points : 1
    Points
    1
    Par défaut
    Oui, en fait je découvre python et je répondais au fil :
    http://www.developpez.net/forums/d80...ements-classe/ pour mettre mes lectures en pratique

    Je regarderai, je suis en train de voir les classes de bases (avant de voir les classes tiers ) et je trouve la solution de kango élégante.

    j'ai quelques interrogations entre autre sur l'utilité des décorateurs que j'ai du mal a voir, l'absence de privé/public et autres (mais j'ai 8 jours de python)

  8. #8
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Points : 970
    Points
    970
    Par défaut
    Citation Envoyé par Antoine_935 Voir le message
    Enfin, si tu es intéressé par plus de puissance, jette un oeuil à ma librairie, et plus précisément Aspyct.utils.Queryable. http://www.aspyct.org
    j'ai été jeté un oeil au lien que tu indiques, je ne maitrise pas du tout la notion de programmation orientée aspect mais j'en ai entendu parlé 2 fois à intervalle réduit (toi et Tyrus si je ne me trompe pas).

    je trouve ton approche propre et engageante, en tout cas tu as attisé ma curiosité

Discussions similaires

  1. lister les instances d'une classe
    Par shadowmoon dans le forum VB.NET
    Réponses: 4
    Dernier message: 04/10/2012, 12h40
  2. [POO] Lister les membres d'une classe
    Par Asmodean dans le forum Langage
    Réponses: 2
    Dernier message: 11/05/2007, 11h28
  3. Connaitre toutes les instances d'une classe
    Par miniseb dans le forum Langage
    Réponses: 14
    Dernier message: 09/01/2006, 17h35
  4. [VB.NET]Reflexion lister les membres d'une classe ...presque
    Par lucie.houel dans le forum ASP.NET
    Réponses: 19
    Dernier message: 20/09/2005, 13h49

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