Forum |  HardWare.fr | News | Articles | PC | Prix | S'identifier | S'inscrire | Shop Recherche
2041 connectés 

  FORUM HardWare.fr
  Programmation
  Python

  [vaguement résolu] surcharger __getattribute__

 



 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[vaguement résolu] surcharger __getattribute__

n°1444915
suizokukan
Posté le 19-09-2006 à 21:48:33  profilanswer
 

Bon, pour ne pas mourir idiot, j'aimerais savoir ce que vous pensez de mon idée de départ et de la manière dont je l'ai implémentée.
 
J'ai une classe C avec de nombreux attributs (des entiers et des fonctions). Pour ce qui est des entiers, j'aimerais pouvoir vérifier automatiquement comment les affectations se font (du genre, interdit d'entrer des valeurs trop grandes). Pour plus de souplesse, je mets mes attributs dans un dictionnaire et j'en contrôle l'accès à l'aide de __getattribute__ / __setattr__ :
 

Code :
  1. class C(dict):
  2.     def __init__(self):
  3.         # les valeurs par défaut :
  4.         self["v1"] = 0
  5.         self["v2"] = 0
  6.        
  7.     def __setattr__(self, name, value):
  8.         if name in self:
  9.             self[name][0] = value
  10.            # ... et j'ajoute ici une vérification sur "value"
  11.         else:
  12.             raise # exception pour signaler qu'on tente de modifier un attribut qui n'existe pas.
  13.     def __getattribute__(self, name):
  14.             if name in self:
  15.                 return self[name]  # je retourne la valeur demandée.
  16.             else:
  17.                 raise # exception pour signaler qu'on tente d'accéder à un attribut qui n'existe pas.
  18.     def foo:
  19.         pass # je coupe : code sans intérêt


Ca fonctionne; mais __getattribute__ intercepte aussi les appels de fonction, par exemple :

Code :
  1. c = C()
  2. c.foo()


... et j'ai droit à un message d'erreur (le raise dans __getattribute__), puisque mon c.__getattribute__ récupère un "foo" en argument et que "foo" n'existe pas dans le dictionnaire. Comment réécrire __getattribute__ de manière à ne pas torpiller les appels aux fonctions de C ?
 
Si vous pouviez me dire ce que vous en pensez... Merci !
 
edit : correction du nom de la fonction dans ma classe.


Message édité par suizokukan le 19-09-2006 à 22:57:03

---------------
rule #1 : trust the python
mood
Publicité
Posté le 19-09-2006 à 21:48:33  profilanswer
 

n°1444929
multani
Dépressionnisé
Posté le 19-09-2006 à 22:14:25  profilanswer
 

Et si tu utilisais des property plutôt ?
 
Si j'ai bien compris ton truc, ça correspond exactement à ce que tu veux faire : http://www.python.org/download/rel [...] /#property

n°1444932
suizokukan
Posté le 19-09-2006 à 22:18:25  profilanswer
 

> multani : merci du coup de main. Je connais les properties mais je ne les utilise pas volontairement. En effet, pour chaque attribut tu dois créer une property. Or je voudrais créer un seul couple de fonctions [get/set] pour vérifier l'accès à toutes les variables de ma classe. Un peu comme s'il existait un property pour un ensemble de variables.


---------------
rule #1 : trust the python
n°1444937
multani
Dépressionnisé
Posté le 19-09-2006 à 22:34:23  profilanswer
 

Tu peux toujours essayer de récupérer par reflexion (avec getattr) une référence vers la méthode, si la clé n'est pas dans le dictionnaire. Mais tu risques d'être coincer au niveau des arguments à passer à la méthode après (je passe la main pour ça).
 
Sinon, ce serait pas plus simple de faire deux fonctions get/set, qui prennent en premier argument le nom de ton attribut ?

n°1444942
suizokukan
Posté le 19-09-2006 à 22:42:45  profilanswer
 

> multani : pour ta deuxième idée, ce serait "plus simple", mais moins élégant. Et ma petite (:)) expérience me prouve qu'il ne faut jamais négliger la simplicité dans la lecture du code d'un projet. D'autant que le mien s'annonce long et difficile (pour moi !)
 
Je me débats donc avec ta première remarque et je cherche toujours un exemple qui me serait accessible d' overriding de la fonction __getattribute__... Et moi, je ne peux pas passer la main. :D  
 
Merci de ton aide.


---------------
rule #1 : trust the python
n°1444946
suizokukan
Posté le 19-09-2006 à 22:56:18  profilanswer
 

Bon, je crois y être arrivé, mais quel merd*** ! Y va falloir que je relise de la doc...
 

Code :
  1. class C(dict):
  2.     def __init__(self):
  3.         dict.__setitem__( self, "v1", 0 )
  4.         dict.__setitem__( self, "v2", 0 )
  5.         self.foo()
  6.     def __setattr__(self, name, value):
  7.         if name in self:
  8.             self[name] = value
  9.         else:
  10.             raise
  11.     def __getattr__(self, name):
  12.         if name in self:
  13.             return dict.__getitem__(self, name)
  14.         else:
  15.             raise
  16.     def foo(self):
  17.         pass


En fait, __getattr__ n'a pas l'air d'intercepter les appels de fonction ... ?!?!
 
Donc voici le comportement attendu (et effectif) de cette classe :

Code :
  1. c = C()
  2. c.v1 = 3 # ok, on passe par __setattr__
  3. print c.v2 # ok, on passe par __getattribute__
  4. c.foo() # ok (donc pas d'interception par __getattribute__)
  5. c.v5 = 0 # raise déclenché par __setattr__
  6. print c.v6 # raise déclenché par __getattribute__


---------------
rule #1 : trust the python
n°1444947
multani
Dépressionnisé
Posté le 19-09-2006 à 22:59:34  profilanswer
 

En fait, je vois pas. On peut pas utiliser getattr dans __getattribute__, sinon, on se mange un "RuntimeError: maximum recursion depth exceeded", donc c'est ratal [:petrus75]

n°1444948
suizokukan
Posté le 19-09-2006 à 23:03:13  profilanswer
 

> multani : et pour clore (?) ce débat, est-ce que tu verrais une autre manière de résoudre le problème initial ? Peut-être est-ce ma classe qui est mal fichue. Sur des détails de conception comme celui-ci, je manque beaucoup d'expérience.
 
Merci pour ton coup de main.


---------------
rule #1 : trust the python
n°1444949
Taz
bisounours-codeur
Posté le 19-09-2006 à 23:07:13  profilanswer
 

avec getattribute, il faut tout faire au niveau de la résolution. y compris déléguer à la classe parente.

n°1444950
suizokukan
Posté le 19-09-2006 à 23:10:01  profilanswer
 

> Taz, c'est vraiment un sujet difficile pour moi, mais je tente de m'accrocher. Pourrais-tu me donner quelques explications ? Ou un bout de code ?


---------------
rule #1 : trust the python
mood
Publicité
Posté le 19-09-2006 à 23:10:01  profilanswer
 

n°1444951
multani
Dépressionnisé
Posté le 19-09-2006 à 23:10:58  profilanswer
 

Là, du coup, je vois pas trop l'intérêt d'hériter de dict ...

n°1445833
masklinn
í dag viðrar vel til loftárása
Posté le 21-09-2006 à 15:42:38  profilanswer
 

Citation :

En effet, pour chaque attribut tu dois créer une property. Or je voudrais créer un seul couple de fonctions [get/set] pour vérifier l'accès à toutes les variables de ma classe. Un peu comme s'il existait un property pour un ensemble de variables.


Résultat tu t'emmerdes et tu fais des trucs crades [:petrus75]


---------------
I've never understood the compulsion to use Web technologies minus the Web's security and deployment models. It seems a bit like throwing the orange away and eating the peel. — @ justinschuh‬

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Python

  [vaguement résolu] surcharger __getattribute__

 

Sujets relatifs
[Résolu]Nombre d'occurrence d'un mot[Résolu] Anjuta , erreur stdio.h
[résolu] calcul fauxComportement Bizare de mon COOKIE [RESOLU]
[Resolu] Addition de deux elements de deux vecteurs[Résolu] [C#] String et Split
[résolu][c#] ajout d un element à un tableausuppression ou cacher ligne sur bouble infini[résolu]
[Résolu][Qt] QProcess lancés en boucle - started() et finished()Récupérer le Full Name d'un utilisateur réseau en VBA [Résolu]
Plus de sujets relatifs à : [vaguement résolu] surcharger __getattribute__


Copyright © 1997-2018 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR