classe et fonction en python **************************** Fonction ======== .. code-block:: python def uneFonction ( unEntier, uneChaine): "documentation de la fonction" print "unEntier : " + str( unEntier ) Fonction avec arguments dynamique ================================= un exemple simple qui permet suivant le nombre d'argument d'appeler la fonction A ou B .. code-block:: python def get( *args): if len(args) == 2: return _get(*args) if len(args) == 3: return _getdefault(*args) raise AttributeError, 'takes 3 or 4 arguments' def _getdefault(section, option, default): if self.config.has_key(section) == False: return default if self.config[section].has_key(option) == False: return default return self.config[section][option] def _get(section, option): if self.config.has_key(section) == False: raise NoSectionError(section) if self.config[section].has_key(option) == False: raise NoOptionError(section, option) return self.config[section][option] Class simple ============ .. code-block:: python class Fruit : "documentation de la classe" def __init__(self) : self._a = 0 # variable privée self.b = 1 #variable public pass def __str__(self): return "ceci est un fruit" def _fonctionPrive(self): "documentation de la fonction" pass def fonctionPublic(self): "documentation de la fonction" pass if __name__ == "__main__": a = Fruit() print a on peut obtenir alors de nombreuse information .. code-block:: python a = Fruit() print a.__dict__ >>{'b': 1, '_a': 0} print a.__doc__ >>documentation de la classe print a.__class__ >> print a.__class__.__dict__.keys() >>['__module__', '_fonctionPrive', 'fonctionPublic', '__str__', '__doc__', '__init__'] print a.__class__.__name__ >>Fruit Heritage ======== .. code-block:: python class Fruit : def __init__(self) : pass class Pomme(Fruit): """ Cette classe represente une pomme. """ Mangeurs = ["Jacques", "Nicolas","Virgile"] def __init__(self, couleur): """ Pour construire une Pomme, donnez sa couleur. """ Fruit.__init__(self) self._couleur = couleur def couleur(self): """ Retourne la couleur de la Pomme. """ return self._couleur def comestible(self, mangeur): """ Dit si la pomme est comestible ou non, en fonction du mangeur. """ if mangeur in self.Mangeurs: print mangeur, "mange des pommes" else: print mangeur, "n'aime pas les pommes" petitePomme = Pomme("verte") petitePomme.comestible("Pierre") # Pierre n'aime pas les pommes petitePomme.comestible("Nicolas") # Nicolas mange des pommes liste des méthodes héritées: .. code-block:: bash __init__ __del__ : suppression __str__ : print __getattr__ __setattr__ __delattr__ __add__ __sub__ __mul__ __mod__ __div__ __divmod__ __comp__ __pow__ __lshift__ __rshit__ __and__ __or__ __xor__ __doc__ pour les collections .. code-block:: bash __len__ __getitem__ __setitem__ __delitem__ __getslice__ __setslice__ un petit exemple d’utilisation .. code-block:: python class foo: a = 0 def __getattr__(self, name): return "%s: DEFAULT" % name i = foo() i.b = 1 print i.a # return 0 print i.b # return 1 print i.c # return c: DEFAULT Utilisation des méthode interne =============================== .. code-block:: python class C(object): def __init__(self): self.x = 0 self.y = 0 def __setattr__(self, name, value): """Ne modifie pas x si la valeur est négative""" if name == 'x' and value < 0: return # Pour tout autre attribut on affecte la valeur object.__setattr__(self, name, value) Utilisation de l’exemple : .. code-block:: bash >>> o = C() >>> o.x, o.y (0, 0) >>> o.x = 7 >>> o.x, o.y (7, 0) >>> o.y = -1 >>> o.x, o.y (7, -1) >>> o.x = -5 >>> o.x, o.y (7, -1) Surcharge des accès aux attributs ================================= La méthode spéciale __getattr__ permet de définir une méthode d'accès à nos attributs plus large que celle que Python propose par défaut. En fait, cette méthode est appelée quand vous tapez objet.attribut (non pas pour modifier l'attribut mais simplement pour y accéder). Python recherche l'attribut et, s'il ne le trouve pas dans l'objet et si une méthode __getattr__ existe, il va l'appeler en lui passant en paramètre le nom de l'attribut recherché, sous la forme d'une chaîne de caractères. :: >>> class Protege: ... """Classe possédant une méthode particulière d'accès à ses attributs : ... Si l'attribut n'est pas trouvé, on affiche une alerte et renvoie None""" ... ... ... def __init__(self): ... """On crée quelques attributs par défaut""" ... self.a = 1 ... self.b = 2 ... self.c = 3 ... def __getattr__(self, nom): ... """Si Python ne trouve pas l'attribut nommé nom, il appelle ... cette méthode. On affiche une alerte""" ... ... ... print("Alerte ! Il n'y a pas d'attribut {} ici !".format(nom)) ... >>> pro = Protege() >>> pro.a 1 >>> pro.c 3 >>> pro.e Alerte ! Il n'y a pas d'attribut e ici ! >>> surcharge modification d'un attribut ==================================== Cette méthode définit l'accès à un attribut destiné à être modifié. Si vous écrivez objet.nom_attribut = nouvelle_valeur, la méthode spéciale __setattr__ sera appelée ainsi : objet.__setattr__("nom_attribut", nouvelle_valeur). Là encore, le nom de l'attribut recherché est passé sous la forme d'une chaîne de caractères. Cette méthode permet de déclencher une action dès qu'un attribut est modifié, par exemple enregistrer l'objet : .. code-block:: python def __setattr__(self, nom_attr, val_attr): """Méthode appelée quand on fait objet.nom_attr = val_attr. On se charge d'enregistrer l'objet""" object.__setattr__(self, nom_attr, val_attr) self.enregistrer() gestion des attributs avec decorator ==================================== Pour gérer des propriétés de classe .. code-block:: python class Mamouth(object): _valeur = "3 calots" @property def valeur(self): return self._valeur.upper() @valeur.setter def valeur(self, valeur): self._valeur = valeur.strip() >>> bille = Mamouth() >>> bille.valeur u'3 CALOTS' >>> bille.valeur = "une pépite " >>> bille.valeur >>> print(bille.valeur) UNE PÉPITE Gestion des docs ================ .. code-block:: python class A: """ la classe la plus simple """ pass a=A() a.__doc__ # return 'la classe la plus simple '