L'introspection en python
Bonjour, je profite d'une petite grippe passagère pour faire un petit article concernant l'introspection python.
supposons la classe suivante :
grades = {'PDG' : 'Directeur Générale', 'cadre' : 'Cadre supérieur', 'chef_dept': 'chef département', 'ouvrier': 'Ouvrier'}
class Employe(object):
def __init__(self, nom, prenom, grade, salaire = 1000.00):
self.nom = nom
self.prenom = prenom
self.salaire = salaire
if grade in grades:
self.grade = grade
else:
raise ValueError(grade)
def augmentation(self):
"""Augmente le salaire selon le grade"""
if grade == 'PDG':
salaire = salaire * 1.3
elif grade == 'cadre':
salaire = salaire * 1.2
else :
salaire = salaire * 1.1
Pour lister le contenu de la classe on peut tout simplement appeler le mot clé dir(object).
>>> e = Employe('Ahmed', 'Mansour', 'cadre')
>>> dir(e)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribut
e__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_e
x__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_
_weakref__', 'augmentation', 'grade', 'nom', 'prenom', 'salaire']
>>> #sans parametres 'dir' donnera les objets en cours
>>> dir()
['Employe', '__builtins__', '__doc__', '__name__', '__package__', 'e', 'grades']
Remarque: dir appelle tout simplement la methode dir de l'objet en question si l'objet n'en a pas python essai du mieux qu'il peut d'en créer (ne liste pas tout).
Différencier entre méthodes et attributs:
>>> for element in dir(e):
... if callable(e.__getattribute__(element)):
... print '%s : methode' % element
... else:
... print '%s : attribut' % element
...
__class__ : methode
__delattr__ : methode
__dict__ : attribut
__doc__ : attribut
__format__ : methode
__getattribute__ : methode
__hash__ : methode
__init__ : methode
__module__ : attribut
__new__ : methode
__reduce__ : methode
__reduce_ex__ : methode
__repr__ : methode
__setattr__ : methode
__sizeof__ : methode
__str__ : methode
__subclasshook__ : methode
__weakref__ : attribut
augmentation : methode
grade : attribut
nom : attribut
prenom : attribut
salaire : attribut
A noter surtout ici c'est la fonction prédéfinie getattribute très utile en métaprogrammation.
Pour lister seulement les attributs "modifiés" de l'instance:
>>> for attr in e.__dict__:
... print 'valeur de %s est %s' % (attr, e.__dict__[attr])
...
valeur de grade est cadre
valeur de nom est Ahmed
valeur de salaire est 1000.0
valeur de prenom est Mansour
NB : l'ordre des attributs diffère de l'ordre des déclarations; la fonction dict n'est pas fiable d'où l'intérêt de la redéfinir ou de passer par les metaclasses.
Trouver le nom d'une classe et ses bases à partir d'une instance:
>>> e.__class__.__name__
'Employe'
>>> e.__class__.__bases__
(<type 'object'>,)
Enfin quelques fonctions prédéfinis très utiles :
>>> hasattr(e, 'nom')
True
>>> hasattr(e, 'surnom')
False
>>> isinstance(e, Employe)
True
>>> issubclass(Employe, type)
False
>>> issubclass(Employe, object)
True
>>> setattr(e, 'prenom', 'Amine')
>>> getattr(e, 'prenom')
'Amine'
>>> e.prenom
'Amine'
Voilà je pense que le compte y est concernant l'introspection :). Bonne journée.

