récupérer nom de la classe mère

récupérer nom de la classe mère - Python - Programmation

Marsh Posté le 21-08-2005 à 18:50:14    

Bonsoir à tous et à toutes.
 
J'ai un grand nombre de classes D1,D2,... dérivées de dict, du genre :

Code :
  1. class D1(dict):
  2. ...


 
J'aimerais savoir comment tester qu'un objet créé par D1 ou par D2, ... a les mêmes propriétés qu'un dictionnaire, pour appliquer la méthode has_key() dessus. Je vois plusieurs solutions :
 
(1) ou bien j'arrive à récupérer le nom de la classe mère (dict) de chaque objet.
(2) ou bien je fais un dir() sur l'objet et je vérifie la présence de has_key(), clear(), copy(), getitems(), par exemple.
(3) ou bien j'attends l'arrivée d'une exception.
(4) ou bien j'ajoute un attribut bidon dans D1,D2,... et je teste la présence de cet attribut dans chaque objet.  
 
 
J'espère que ma question n'est pas trop c****... merci de m'aider


Message édité par suizokukan le 21-08-2005 à 18:51:30
Reply

Marsh Posté le 21-08-2005 à 18:50:14   

Reply

Marsh Posté le 22-08-2005 à 09:51:22    

isinstance(obj, dict)

Reply

Marsh Posté le 22-08-2005 à 10:00:48    

suizokukan a écrit :

(1) ou bien j'arrive à récupérer le nom de la classe mère (dict) de chaque objet.
(2) ou bien je fais un dir() sur l'objet et je vérifie la présence de has_key(), clear(), copy(), getitems(), par exemple.
(3) ou bien j'attends l'arrivée d'une exception.
(4) ou bien j'ajoute un attribut bidon dans D1,D2,... et je teste la présence de cet attribut dans chaque objet.  
 
 
J'espère que ma question n'est pas trop c****... merci de m'aider


ou alors tu utilises tout simplement hasattr [:spamafote]

>>> class Object(dict):
...     pass
...
>>> o = Object()
>>> hasattr(o, "has_key" )
True


Edit: utiliser hasattr permet de faire du duck typing (*): au lieu de tester ce qu'est l'objet, on teste ce dont il est capable, et si ses capacités correspondent à ce qu'on veut alors il est valide.
 
Parce que, par exemple

>>> import UserDict
>>> class Object(UserDict.UserDict):
...     pass
...
>>> a = Object()
>>> isinstance(a, dict)
False


alors que UserDict est un dictionnaire parfaitement classique (c'était la classe dictionnary dérivable avant que "dict" ne le soit), simplement comme UserDict n'est pas dérivé de dict Object ne l'est pas non plus, et a n'est donc pas une instance de dict.
 
(*) Duck Typing, principe formalisé sur une mailing list Ruby:

Citation :

if it looks like a duck and it quacks like a duck, it's a duck


=> Si ça a une tête de canard et que ça fait un bruit de canard, alors c'est un canard.
 
Avantage, c'est que pour les langages hautement dynamiques comme Python ou Ruby dans lesquels on peut très facilement rajouter des membres/méthodes on se base sur les capacités des objets et non sur leur classe initiale (qui n'a en fait aucune importance)


Message édité par masklinn le 23-08-2005 à 08:47:53

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 22-08-2005 à 18:50:34    

> dividee, Masklinn : merci pour vos réponses. Et merci à Masklinn de donner de ton temps pour expliquer.
 
edit : typos


Message édité par suizokukan le 22-08-2005 à 18:55:51
Reply

Marsh Posté le 22-08-2005 à 20:12:02    

Si tous les types admissibles ne descendent pas d'un ancètre commun, je préférerais utiliser un try/except plutôt qu'une série de hasattr; ça me parait plus simple, plus clair et plus efficace:

try:
    obj.has_key(0)
    obj.items()
except AttributeError:
    # obj is not dictionary-like

plutôt que

if hasattr(obj, 'has_key') and hasattr(obj, 'items'):
    obj.has_key(0)
    obj.items()
else:
    # obj is not dictionary-like

La documentation de la fonction hasattr précise d'ailleurs qu'elle est implémentée en appelant getattr et en vérifiant si elle lève ou non une exception.

Citation :

It's easier to ask forgiveness than permission

Reply

Marsh Posté le 23-08-2005 à 04:02:31    

has_key c'est nul, ça pue
 
if k in d:
   blah

Reply

Marsh Posté le 23-08-2005 à 04:27:38    

par ailleurs, python support l'héritage multiple, tu as donc potentiellement plusieurs super-classes
 

>>> class Foo(object): pass
...
>>> class Bar(Foo, dict): pass
...
>>> Bar.mro()
[<class '__main__.Bar'>, <class '__main__.Foo'>, <type 'dict'>, <type 'object'>]


 
la méthode mro() (method resolution order) de la classe object te donne l'ordre de résolution des appels de méthodes en t'indiquant la classe et les super-classes.

Reply

Marsh Posté le 23-08-2005 à 09:00:42    

dividee a écrit :

Si tous les types admissibles ne descendent pas d'un ancètre commun, je préférerais utiliser un try/except plutôt qu'une série de hasattr; ça me parait plus simple, plus clair et plus efficace


Et plus fréquent en python aussi :jap:


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
Reply

Marsh Posté le 24-08-2005 à 10:13:55    

Merci à tous pour ces renseignements très intéressants.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed