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 :

bonne pratique - référence d'instances


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 15
    Par défaut bonne pratique - référence d'instances
    Bonjour !

    Je vais dans le cadre d'une application créer des instances à la volée, dont je ne peux prévoir le nombre avant. Le but est de les 'indexer', en tout cas de pouvoir les rappeler plus tard pour agir dessus (par méthodes ...).

    Je pensais au départ retourner l'id de la fonction par la fonction __init__, or celle-ci ne peut rien retourner.

    J'ai alors pensé à instancier par la commande id(Classe()), ce qui retourne effectivement l'id. Je comptais rappeler plus tard cette instance par son id. Cependant, d'après ce que j'ai compris, comme Python détruit ce qui n'est plus référencé, le ramasse-miettes va libérer cette instance à la première occasion.

    Il devient donc apparemment nécessaire d'instancier sous une forme instance = Classe(). Ma question se pose ici : comment choisir la référence ? génération aléatoire ? Existe t-il des bonnes pratiques en la matière ?

    Merci de votre avis

  2. #2
    Membre émérite

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Par défaut
    S'il s'agit de créer des instances à la volée et de garder une référence dessus, il te suffit de les garder dans une liste stockée comme variable de classe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> class A:
    ...     instances = []
    ...     def __init__(self):
    ...         # Constructeur habituel
    ...         A.instances.append(self)
    ... 
    >>> inst = [A() for i in range(10)]
    >>> inst
    [<__main__.A instance at 0x8661bec>, <__main__.A instance at 0x8661b4c>, <__main__.A instance at 0x8661d6c>, <__main__.A instance at 0x8661d8c>, <__main__.A instance at 0x8661dac>, <__main__.A instance at 0x8661dcc>, <__main__.A instance at 0x8661dec>, <__main__.A instance at 0x8661e2c>, <__main__.A instance at 0x8661e4c>, <__main__.A instance at 0x8661e6c>]
    >>> A.instances
    [<__main__.A instance at 0x8661bec>, <__main__.A instance at 0x8661b4c>, <__main__.A instance at 0x8661d6c>, <__main__.A instance at 0x8661d8c>, <__main__.A instance at 0x8661dac>, <__main__.A instance at 0x8661dcc>, <__main__.A instance at 0x8661dec>, <__main__.A instance at 0x8661e2c>, <__main__.A instance at 0x8661e4c>, <__main__.A instance at 0x8661e6c>]

  3. #3
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

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

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    Bonjour,

    Question interessante J'ai été confronté à ce type de problème et j'ai choisi de créer un registre externe à la classe sous forme d'un WeakValueDictionary du module weakref et j'ai une métaclasse utilisée par tous mes objets qui inscrit les instances dans ce registre. Ce registre est commun à tous les types d'objets.

    Je ne sais pas si ce type de conception est une "bonne pratique", aussi je suis vraiment curieux de voir les réponses à ce topic.

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    En ce qui me concerne, j'utilise dans ce cas une liste qui porte les instances de classe: c'est simple et ça marche très bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    L = []
     
    # création des instances
    L.append(A())
    L.append(A())
     
    # appel des instances:
    x = L[0].attributdeclasse
    L[1].methodedeclasse(a, b, c)
     
    # Balayage de toutes les instances:
    for l in L:
        z = l.methodedeclasse(u,v)
    On utilise ça aussi avec les classes thread (module threading) quand on ne sait pas combien il y aura d'instances, ou que leur nombre varie constamment.

    Tyrtamos

  5. #5
    Membre émérite
    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
    Par défaut
    J'avais exposé une des solutions possibles dans un précédent post:
    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
    >>> class Collector(list):
    ...     def __call__(self, init):
    ...         def newInit(itself, *args, **kwargs):
    ...             init(itself, *args, **kwargs)
    ...             self.append(itself)
    ...
    ...         return newInit
    ...
    >>> collector = Collector()
    >>>
    >>> class MyTrackedClass(object):
    ...     @collector
    ...     def __init__(self):
    ...         pass
    ...
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E550>
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E430>
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E710>
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E730>
    >>> collector
    [<__main__.MyTrackedClass object at 0x0231E550>, <__main__.MyTrackedClass object
     at 0x0231E430>, <__main__.MyTrackedClass object at 0x0231E710>, <__main__.MyTra
    ckedClass object at 0x0231E730>]
    Avec ce code, peu importe où et comment tu crées l'objet, si l'instanciation a réussi, alors cet objet sera listé dans collector.
    Tu peux bien sûr mettre des weakref dans collector si ça te chante.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 15
    Par défaut
    Intéressant d'avoir plusieurs réponses différentes

    Pour Antoine_935 : si on utilise les weakref, comment peut-on alors faire pour revenir chercher dans le collector l'objet que l'on souhaite ? Par exemple, si un des objets placé avant dans la liste a été détruit car n'est plus utilisé ailleurs, tout va être décalé d'un cran non ? Ou alors est-ce qu'on obtient une liste du type [Objet1,Objet2,void,Objet3] ?

  7. #7
    Membre chevronné
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Par défaut
    Citation Envoyé par Antoine_935 Voir le message
    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
    >>> class Collector(list):
    ...     def __call__(self, init):
    ...         def newInit(itself, *args, **kwargs):
    ...             init(itself, *args, **kwargs)
    ...             self.append(itself)
    ...
    ...         return newInit
    ...
    >>> collector = Collector()
    >>>
    >>> class MyTrackedClass(object):
    ...     @collector
    ...     def __init__(self):
    ...         pass
    ...
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E550>
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E430>
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E710>
    >>> MyTrackedClass()
    <__main__.MyTrackedClass object at 0x0231E730>
    >>> collector
    [<__main__.MyTrackedClass object at 0x0231E550>, <__main__.MyTrackedClass object
     at 0x0231E430>, <__main__.MyTrackedClass object at 0x0231E710>, <__main__.MyTra
    ckedClass object at 0x0231E730>]
    Belle utilisation des décorateurs, j'aime beaucoup... . J'avais jamais trouvé de réel cas d'utilisation, mis à part pour les framework...

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

Discussions similaires

  1. Bonnes pratiques de protections individuelles
    Par Community Management dans le forum Sécurité
    Réponses: 23
    Dernier message: 11/06/2024, 11h23
  2. [2012] Bonne Pratique de déploiement SSISDB en multi-instance
    Par GeekMokona dans le forum SSIS
    Réponses: 2
    Dernier message: 08/12/2014, 11h52
  3. Ouvrage de référence sur les bonnes pratiques pour le design d'un site
    Par Schim59 dans le forum Webdesign & Ergonomie
    Réponses: 0
    Dernier message: 24/07/2012, 08h43
  4. Réponses: 0
    Dernier message: 02/12/2010, 15h39
  5. Bonne pratique : Résolution de portée ou référence ?
    Par FrontLine dans le forum Langage
    Réponses: 20
    Dernier message: 20/05/2008, 09h31

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