Définir et manipuler des classes ================================= .. glossary:: objet Un object est une entité possédant un type, un état, et un comportement. Un object correspondant généralement à une entité du monde réel, mais cette entité peut être abstraite. On parle aussi d'**instance**. **état d'un objet** : ensemble de propriétés auxquelles sont associées des valeurs. Les variables de l'objet sont appelées des **attributs**. le comportement d'un :term:`objet` : - des actions effectuées sur l'objet - des appels faits sur l'objet envois de messages à l'objet = appel de **méthodes** classes d'objets ------------------ - encapsulation (cacher les attributs (variables d'état)) d'un objet. - interfaces : chaque aspect d'une classe peut être vu comme une interface. Une interface décrit un ensemble de comportements. on peut considérer une interface comme un protocole d'utilisation d'un objet dans un contexte donné. On peut alors créer des outils qui sauront traiter n'importe quel objet pourvu qu'il respecte un ensemble d'interfaces. .. todo:: travailler l'héritage, l'agrégation, la délégation Voici un exemple de classe `Voiture` : .. literalinclude:: snippets/heritage.py :pyobject: Voiture j'instancie ma classe `Voiture` : >>> ma_voiture = Voiture("ma_marque", "150km/h") >>> ma_voiture.roule() 'vroummm' >>> ma_voiture.signaletique() 'constructeur : ma_marque, vitesse_max 150km/h' .. todo:: faire des traitements dans l'init - héritage (est une sorte de) - polymorphisme : un objet apparait comme une instance d'une classe parente .. literalinclude:: snippets/heritage.py :pyobject: Turbo >>> v = DoDoche("marque", 160) >>> v.get_prix() '7000' >>> isinstance(v, Prix) True >>> mais l'objet conserve son identité : >>> type(v) la fonction ``achete_voiture()`` sera appelée indépendamment du type de l'objet, du moment que l'objet a une méthode `get_prix()`, c'est le duck typing, qu'il est préférable de ramener au polymorphisme d'objet, ou bien utiliser les :mod:`abc` (abstract base classes). .. literalinclude:: snippets/heritage.py :pyobject: achete_voiture tout le code : .. literalinclude:: snippets/heritage.py :download:`télécharger le code ` - **l'aggrégation** un attribut est lui-même un objet (ce qui est fréquent en python)... .. literalinclude:: snippets/aggregation.py - **la délégation** la fonction "property" est un élément du design de python lui-même .. function:: property() les patrons de conception --------------------------- - le patron **factory** .. literalinclude:: snippets/patrons.py :download:`télécharger usine (factory) ` - le patron **wrapper** :download:`télécharger wrapper ` .. literalinclude:: snippets/wrap.py exemple d'utilisation de `Wrap()` >>> class O: ... pass ... >>> o = O() >>> o.a = "blah" >>> >>> from wrap import Wrap >>> w = Wrap("monwrap", o) >>> w._name 'monwrap' >>> w._w <__main__.O instance at 0x7fbf177aaa28> >>> w._w.a 'blah' >>> w.a 'blah' >>> w.u Traceback (most recent call last): File "", line 1, in File "wrap.py", line 11, in __getattr__ return getattr(self._w, name) AttributeError: O instance has no attribute 'u' >>> - le patron de conception **itérable** :download:`télécharger iterable ` .. literalinclude:: snippets/iterable.py - le patron **decorateur** :download:`télécharger decorateur ` .. literalinclude:: snippets/decorateur.py >>> def deco(func): ... func.attr = 'decorated' ... return func ... >>> @deco ... def f(): pass ... >>> f.attr 'decorated' >>>