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 :

defaultdict: changer __setitem__ sur une instance


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut defaultdict: changer __setitem__ sur une instance
    Bonjour,

    J'ai une classe D dérivant de object et de collections.defaultdict, dont je redéfinis le __setitem__. Je voudrais que sur une clef manquante, defaultdict.__setitem__ soit appelé, plutot que D.__setitem__ (car defaultdict.__getitem__ appelle __setitem__ sur une clef manquante ).

    Je ne veux pas surcharger D.__getitem__ pour des raisons de performance.

    Que pensez-vous de la solution suivante ?
    J'espère que la fonction générant les __missing__ est appelée uniquement "au bon moment".

    Merci d'avance

    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
     
    from collections import defaultdict
    from itertools import repeat
     
    class UseDefaultDictGetItem(defaultdict,object):
        __getitem__ = defaultdict.__getitem__
     
    class shield:
        def __init__(self,obj):
            self.obj=obj
        def __enter__(self):
            assert self.obj.shield
            self.obj.shield= False
            self.temp= self.obj.__class__           
            self.obj.__class__= UseDefaultDictGetItem
            return self
        def __exit__(self, type, value, traceback):
            assert not(self.obj.shield), "state discrepancy, (don't call the __missing__, don't use threads?)"
            assert self.temp, "no class to setback"
            self.obj.__class__= self.temp# self.obj._basicclass
     
    class D(defaultdict,object):
        """ Redirects [missing.__setattr__] to defaultdict """
        def shieldDefault(self): self.shield= True # returns None for dd.__init__()
        def __init__(self, ):
            #self._basicclass= self.__class__
            self.shield= False
            self.lock= shield(self)
            defaultdict.__init__(self, self.shieldDefault )#repeat(None).next)
        def __setitem__(self, k,v):
            if self.shield:            
                with self.lock: self[k]=v #v= defaultdict.__setitem__(self, k,v) #defaultdict ne marche pas                                                               
            else:            
                print " CALLS D.setitem"
                defaultdict.__setitem__(self, k,v)
     
    if __name__ == '__main__':
        y= D()    
        print "y[0]:"
        print y[0] # D.__setitem__ n'est pas appelé (valeur manquante)
        print "set et y[0]:"
        y[0]=1
        print y[0] # D.__setitem__ est appelé (key presente)

  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,

    Je n'ai pas encore tout compris mais en lisant le 'besoin' en français, je me demande pourquoi faire plus compliqué que çà:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    cclass foo(dict):
        def __missing__(self, k):
            print ('__missing__')
            dict.__setitem__(self, k, None) 
     
    class D(foo):
        def __setitem__(self, k, v):
            print ('__setitem__')
            return foo.__setitem__(self, k, v)

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

  3. #3
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    J'ai trois questions.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        def __setitem__(self, k, v):
            if self.shield:            
                with self.lock:
                    self[k] = v  # v = defaultdict.__setitem__(self, k, v) #defaultdict ne marche pas                                                               
            else:            
                print " CALLS D.setitem"
                defaultdict.__setitem__(self, k, v)
    Vu que l'on hérite de defaultdict que l'on écrive defaultdict.__setitem__(self, k, v) ou self[k] = v de toute manière c'est D.__setitem__ qui est utilisé, donc c'est le __setitem__ de defaultdict qui est utiliser: Ou est le tour de passe passe ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    class UseDefaultDictGetItem(defaultdict, object):
    class D(defaultdict, object):
    Pourquoi hériter de object ?

    Ce n'est pas compliquer inutilement la chose ?

    @+

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 062
    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 : 4 062
    Par défaut
    Hello,

    J'ai une autre question, tu parles beaucoup de performances dans tes posts, perso je trouve ça en contradiction avec la POO, ne ferais-tu pas fausse route?

  5. #5
    Membre Expert
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Par défaut
    Merci beaucoup pour vos réponses

    pourquoi faire plus compliqué que çà
    Effectivement, __missing__ est bien mieux dans mon cas !

    *Pourquoi hériter de object-> J'ai besoin de descripteurs sur D

    * Ou est le tour de passe passe
    En se servant du else comme un Hook. Par exemple ici, send_message_reseau()- la version surchargée par D de __setitem__ - n'est pas appelée depuis defaultdict.__getitem__.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if self.shield:            
                with self.lock:
                    self[k] = v  # v = defaultdict.__setitem__(self, k, v) #defaultdict ne marche pas                                                               
            else: # HOOK: overloaded setitem            
                send_message_reseau(self,k,v)
    @fred: Bah mon code utilise la POO, mais après profiling, j'essaye d'améliorer la situation.

  6. #6
    Membre Expert Avatar de PauseKawa
    Homme Profil pro
    Technicien Help Desk, maintenance, réseau, système et +
    Inscrit en
    Juin 2006
    Messages
    2 725
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Technicien Help Desk, maintenance, réseau, système et +
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 725
    Par défaut
    Bonjour,

    Citation Envoyé par VV33D Voir le message
    *Pourquoi hériter de object-> J'ai besoin de descripteurs sur D
    ? C'est à dire ? De quoi avez vous besoin pour D que vous n'ayez besoin de cet héritage ?

    Citation Envoyé par VV33D Voir le message
    * Ou est le tour de passe passe
    En se servant du else comme un Hook. Par exemple ici, send_message_reseau()- la version surchargée par D de __setitem__ - n'est pas appelée depuis defaultdict.__getitem__.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    if self.shield:            
                with self.lock:
                    self[k] = v  # v = defaultdict.__setitem__(self, k, v) #defaultdict ne marche pas                                                               
            else: # HOOK: overloaded setitem            
                send_message_reseau(self,k,v)
    Voila qui ne vas pas arranger ma compréhension...
    Pour moi self[k] = v fait appel au __setitem__ de defaultdict.

    @+

  7. #7
    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 PauseKawa Voir le message
    Pour moi self[k] = v fait appel au __setitem__ de defaultdict.
    Pour ce que j'en ai compris, la question est d'éviter de passer par D.__setitem__ lorsqu'on initialise la clé, pour éviter le délai d'acquisition du verrou... mais comme "verrou" = multithreads (au moins dans ma tête), c'est plutôt "dangereux".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

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

Discussions similaires

  1. Réponses: 2
    Dernier message: 20/02/2009, 10h36
  2. problème de connexion sur une instance 9i
    Par abadana dans le forum Administration
    Réponses: 1
    Dernier message: 19/12/2008, 18h26
  3. Satistiques sur une instance
    Par loulag07 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 23/04/2008, 15h20
  4. Réponses: 4
    Dernier message: 14/09/2007, 08h41
  5. Réponses: 1
    Dernier message: 18/07/2007, 17h18

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