OVH Cloud OVH Cloud

nouveau modèle objet

6 réponses
Avatar
JB Richet
bonjour,

je me suis fait acheter par ma boîte l'ouvrage "Python en concentré" qui
est sorti en janvier chez O'Reilly. Comme toujours chez cet éditeur,
c'est excellent (hormis quelques coquilles pardonnables).

La lecture m'a notamment fait découvrir l'existence d'un "nouveau modèle
objet" que les précédents livres lus sur le langage n'évoquaient même
pas, apparu avec la version 2.2 de l'interpréteur. Le chapitre est
uniquement théorique, et j'avoue ne pas tout comprendre.

La différence la plus notable quand on crée une classe en héritant la
classe 'object', c'est la méthode __new__. Bon, je vois à peu près
l'intérêt : création pure et simple, et la méthode __init__ se contente
de l'initialisation au sens strict. C'est plus clair.

Mais il y a aussi des méthodes statiques et des méthodes de classe, et
je n'ai pas compris leur intérêt.

La notion de propriété me semble très élégante, permettant de présenter
les définitions d'un élément d'une classe de façon compacte et claire.
On gagne en développement et en maintenance.

Par contre, je n'ai pas compris le paragraphe qui traite de l'appel
coopératif des méthodes des superclasses. Mais je crois pouvoir m'en
passer vu que je ne fais aucun héritage multiple. A vérifier.
j'avancerai prudemment dès qu'il y aura héritage...

Il me reste à lire le chapitre sur les métaclasses, ce sera pour demain,
mais vu l'intro, j'ai peur que ce soit un peu obscure.

Pourriez-vous m'aider à y voir plus clair, ou m'indiquer d'autres lectures ?

merci à tous,
JBR

6 réponses

Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
+1


Et, en plus, quelques explications sur les métaclasses seraient aussi
appréciées.
Avatar
Yermat
JB Richet wrote:
bonjour,
[...]
Mais il y a aussi des méthodes statiques et des méthodes de classe, et
je n'ai pas compris leur intérêt.


Aie. Ca c'est la base aussi... Disons qu'une méthode reçoit comme
premier argument une instance d'objet; une méthode de classe reçoit la
classe elle-même; alors qu'une fonction statique ne reçoit pas de
premier argument particulier.

Voir un exemple sur
http://www.python.org/cgi-bin/moinmoin/SingletonProgramming

La notion de propriété me semble très élégante, permettant de présenter
les définitions d'un élément d'une classe de façon compacte et claire.
On gagne en développement et en maintenance.


Exact et surtout on peut changer d'idée en court de route sans tout
récrire...

Par contre, je n'ai pas compris le paragraphe qui traite de l'appel
coopératif des méthodes des super classes. Mais je crois pouvoir m'en
passer vu que je ne fais aucun héritage multiple. A vérifier.
j'avancerai prudemment dès qu'il y aura héritage...


Pour cela, il faut se baser sur le fameux diagramme de classe en losange
(diamond).
Voir par exemple
http://www.python.org/doc/newstyle.html
http://www.python.org/2.2.3/descrintro.html

Il me reste à lire le chapitre sur les méta classes, ce sera pour demain,
mais vu l'intro, j'ai peur que ce soit un peu obscure.
[...]


Les méta-classes... Disons que c'est une personnalisation de comment les
classes réagissent. Ça permet de faire pas mal de choses différentes.
L'exemple le plus commun c'est de rajouter la vérification de pré- et
post-conditions au méthodes. Voir pour cela les exemples livrés avec
python :
<python2.3>/Demo/newmetaclasses/
<python2.3>/Demo/metaclasses/

ou encore les différents liens situés sur la première page citée.

--
Cordialement,
yermat

Avatar
poyol
"Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle." wrote in message news:<cem145$sk1$...
+1


Et, en plus, quelques explications sur les métaclasses seraient aussi
appréciées.



Des explications, des explications....

C'est trop vague !

A la rigeur, un exemple que tu ne comprends pas et on te reponds sur
ca.

Pour les meta classes, un papier (anglais) que j'avais bien apprecie
etait celui de Dr. Mertz, sur ibm developper workds (google ibm,
charming python ....)

Pour le reste ,

methode static et de classes:
*En python* (notez les '*') on a
staticmethod(func)->func
Cela sert, dans le cadre d'une classe a proposer une methode qui ne
porte pas sur la classe ni sur une instance, mais qui doit quand meme
etre attachée a la classe.

par exemeple, pour la classe dict, la methode dict.fromkeys est
statique.

tu l'appelles depuis la classe dict et non pas une de ces instances.

Un exemple d'utilisation classque (comme dict.fromkeys, d'ailleurs) et
pour la creation d'instance de la classe. Une pseudo-forme de factory.
Pour rappel, la methode statique dict.fromkeys prends en entrée un
tableaux de valeurs et renvoie une instance de dictionnaire, qui
possede comme clefs chacune des valeurs passées.
Comme on peut le voir sur cette exemple, on a bien une methode qui est
en rapport avec les dictionnaires (vu que ca en renvois un) mais qui
n'a pas besoin de la classe on d'une instance de la classe pour
fonctionner.

Du coup, l'avantage, c'est que dans la signature de la classetu n'as
pas besoin de 'self' (on pardonnera le raccourcis, mias bon, c'est
comprehensible)

class toto:
def methodClassqiue(self, obj):print obj

def methodStatic() :#<- rien !!
print 'coucou'
methodStatic=staticmethod(methodStatic)

t=toto()
t.methodStatic()
-> coucou
toto.methodStatic()
-> coucou

Alors que self n'est pas en parametre.

Pour les methodes de classes ,c'est quasiment pareil, sauf que dans la
signature, ce n'est pas self, une etiquette sur un nom d'instance que
l'on veut recevoir, mais 'klass' (ou n'importe quoi bien sur) une
etiquette sur la classe elle même.

Encore une fois, pour bien comprendre ce qui se passe, n'hesitez pas a
faire des
def toto(*args):print args

pour comprendre ce qui est recu et comment c'est recu.


Pour ce qui est de "'appel coopératif des méthodes des superclasses""
effectivement, ca ne m'a jamais trop servis.
C'est juste qu'il y a un ordre d'appel, qui est place au niveau de la
classe ou de l'instance (je ne sais plus), denote par mro (mzo ?) et
qui permet juste de regler des conflits d'appels 'en carreaux'
(traduction litteralle de diamonds call).
Tu comprends quand ca t'arrivera justement.


Voila, et pour terminer, les metaclasses, on croit que c'est obscure,
mais encore une fois c'est un coup a prendre.
Il faut juste s'imaginer qu'une classe, en tant objet, a elle même une
classe dont elle est instance. Pour ne pas se brouiller dans les
termes, il me semble bien qu'on dira, en python, qu'on objet est
instance d'une classe et qu'une classe est instance d'un type.
De base, tous les objets on le type que leur fournit la classe dont
ils sont instances.
Par exemple, si un objet derive de la classe objet, il aura le type
'instance', et le type de son type sera bien le type de sa classe
(object) donc 'type'.

Sympa comme phrase !
Maintenant, vous êtes encore plus embrouille.

Tout ca pour dire que cela permet de modifier massivement des classes
entieres *a la creation de la classe*.

Grosso modo, pour vous donner un parallelle (et pour me la peter) ca
me permet de modfifier en 4 lignes bien placer toutes les classes de
la librairies wxPython pour que ceux ci aient des proprietes en plus
de leur Getter & Setter
Exemple:
en plus de frame.GetSize et frame.SetSize, ma metaclass rajoute
automatiquement a la creation de la classe une propriete Size tel que
print frame.Size appelle frame.GetSize()
frame.Size=1 appelle frame.SetSize(1)

Clean, non !



Voili voilou,

En epserant que cela siot utile et pas trop pleins d'incorrections
---OPQ

Avatar
JB Richet
salut,
et merci de ta réponse. elle attire quelques questions complémentaires
OPQ wrote:

Pour les meta classes, un papier (anglais) que j'avais bien apprecie
etait celui de Dr. Mertz, sur ibm developper workds (google ibm,
charming python ....)

j'ai lu le paragraphe dans mon bouquin. ça vole très haut, j'ai pas tout

compris, mais du peu que j'ai pigé je dois pouvoir vivre sans. Donc pour
l'heure, je laisse de côté
Pour le reste ,

methode static et de classes:
*En python* (notez les '*') on a
staticmethod(func)->func
Cela sert, dans le cadre d'une classe a proposer une methode qui ne
porte pas sur la classe ni sur une instance, mais qui doit quand meme
etre attachée a la classe.

par exemeple, pour la classe dict, la methode dict.fromkeys est
statique.

tu l'appelles depuis la classe dict et non pas une de ces instances.

Un exemple d'utilisation classque (comme dict.fromkeys, d'ailleurs) et
pour la creation d'instance de la classe. Une pseudo-forme de factory.
factory ? C'est du C++ ? Python est le seul langage orienté objet que je

connaisse.
Pour rappel, la methode statique dict.fromkeys prends en entrée un
tableaux de valeurs et renvoie une instance de dictionnaire, qui
possede comme clefs chacune des valeurs passées.
Comme on peut le voir sur cette exemple, on a bien une methode qui est
en rapport avec les dictionnaires (vu que ca en renvois un) mais qui
n'a pas besoin de la classe on d'une instance de la classe pour
fonctionner.

Du coup, l'avantage, c'est que dans la signature de la classetu n'as
pas besoin de 'self' (on pardonnera le raccourcis, mias bon, c'est
comprehensible)

class toto:
def methodClassqiue(self, obj):print obj

def methodStatic() :#<- rien !!
print 'coucou'
methodStatic=staticmethod(methodStatic)

t=toto()
t.methodStatic()
-> coucou
toto.methodStatic()
-> coucou

Alors que self n'est pas en parametre.
en effet, sans la ligne truc = staticmethod(bidule), ça ne fonctionne pas.

Dans ton exemple, la classe ne dérive pas de la classe object. C'est
donc une fonctionnalité qui est disponible également dans le modèle
objet classique de python ?
Jusque là j'avais une ou deux fonctions qui se balladaient à côté des
classes pour lesquelles elles sont utiles, cela me permettra de les
ramener dans le giron de l'une d'elles. Cela peut être élégant.

Pour les methodes de classes ,c'est quasiment pareil, sauf que dans la
signature, ce n'est pas self, une etiquette sur un nom d'instance que
l'on veut recevoir, mais 'klass' (ou n'importe quoi bien sur) une
etiquette sur la classe elle même.
j'ai lu dans ce bouquin que la convention pour le premier paramètre

d'une méthode de classe est 'cls'


Pour ce qui est de "'appel coopératif des méthodes des superclasses""
effectivement, ca ne m'a jamais trop servis.
C'est juste qu'il y a un ordre d'appel, qui est place au niveau de la
classe ou de l'instance (je ne sais plus), denote par mro (mzo ?) et
qui permet juste de regler des conflits d'appels 'en carreaux'
(traduction litteralle de diamonds call).
Tu comprends quand ca t'arrivera justement.
ok pour la différence des ordres de recherche dans les différents

domaines de noms des différentes classes héritées : on n'a plus une
recherche en profondeur puis de gauche à droite, comme dans le modèle
classique, mais une recherche de gauche à droite puis en profondeur.

C'est l'instruction super() qui me pose problème. Il semble que lorsque
elle est présente, le compilateur recherche toutes les occurences de la
fonction demandée dans toute l'arborescence, plutôt que de s'arrêter à
la première trouvée. Je comprends pas bien.


Voila, et pour terminer, les metaclasses, on croit que c'est obscure,
mais encore une fois c'est un coup a prendre.
Il faut juste s'imaginer qu'une classe, en tant objet, a elle même une
classe dont elle est instance. Pour ne pas se brouiller dans les
termes, il me semble bien qu'on dira, en python, qu'on objet est
instance d'une classe et qu'une classe est instance d'un type.
De base, tous les objets on le type que leur fournit la classe dont
ils sont instances.
Par exemple, si un objet derive de la classe objet, il aura le type
'instance', et le type de son type sera bien le type de sa classe
(object) donc 'type'.

Sympa comme phrase !
Maintenant, vous êtes encore plus embrouille.

Tout ca pour dire que cela permet de modifier massivement des classes
entieres *a la creation de la classe*.

Grosso modo, pour vous donner un parallelle (et pour me la peter) ca
me permet de modfifier en 4 lignes bien placer toutes les classes de
la librairies wxPython pour que ceux ci aient des proprietes en plus
de leur Getter & Setter
Exemple:
en plus de frame.GetSize et frame.SetSize, ma metaclass rajoute
automatiquement a la creation de la classe une propriete Size tel que
print frame.Size appelle frame.GetSize()
frame.Size=1 appelle frame.SetSize(1)

Clean, non !
c'est bien ce qui me semblait, je devrais pouvoir vivre sans.


En epserant que cela siot utile et pas trop pleins d'incorrections
---OPQ
coquilles mises à part, c'était utile. merci.

JBR

Avatar
Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle.
Bonsoir !

Mais quelles différences "réelles" y a t'il, entre les métaclasses, et les
superclasses ? Dans ton exemple, pour wxPython, rien n'empêcherait de faire
une classe intermédiaire, qui fournirait le "Size", et d'en faire hériter
les autres, non ?

@+
--
Michel Claveau
Avatar
poyol
"Michel Claveau - abstraction méta-galactique non triviale en fuite perpétuelle." wrote in message news:<cep29u$g9h$...
Bonsoir !

Mais quelles différences "réelles" y a t'il, entre les métaclasses, et les
superclasses ? Dans ton exemple, pour wxPython, rien n'empêcherait de faire
une classe intermédiaire, qui fournirait le "Size", et d'en faire hériter
les autres, non ?

@+


La difference n'est pas dans le resultat mais dans l'implementation.

Si tu fais une super classe, justement, comme tu le dis si bien, il va
falloir que tu te creuses un peu la tete, avec les API et que tu crées
à la mimine un element Size. De même pour tous les autres attributs
des classes.
Et accessoirement que tu fasses ca à plusieurs endroits, puisque tous
les objets n'on pas forcement de Size en wxPython.

Avec la metaclasse, je ne change pas l'héritage d'une instance de
classe. Je dis juste que à partir de maintenant, tu n'est plus une
instance d'un objet de type classe mais une instance d'une objet de
type SupraMAchinTruc.

Et que donc, sont fonctionnement n'est pas forcement le même que celui
d'une classe.
Et c'est ce fonctionnement que je definis dans la metaclass.

Au moment ou la classe (et non pas l'instance) est crée (c'est à dire
lorsque l'interpreteur lit le code de la classe pour en faire du
bytecode), la metaclass intervient pour faire de subtile petit
changement.

Par exmple, moi, avec ma meta classe wxPython, je dis juste:
regarde tous tes attributs. Si il y en a un qui s'appelle GetTOTO et
un autre SetTOTO, alors créer une propertie avec GetTOTO et SetTOTO et
appelle la TOTO.
Et boucle sur tous les attributs.

Donc, c'est fait indepemment de la classe elle meme. Je n'ai pas a
savoir qu'un objet a bien un GetSize et que donc il merite un attribut
Size.
C'est la meta class, qui change la notion meme de classe qui permet
ca.


Ceci etant, cela donne la l'utilite la plus courante d'une classe, a
savoir ajouter automatiquement des attributs a la creation.

Mais dans l'exmple du Dr Mertz (cf post de moi meme ci dessus) il y
avait me semble-t-il une autre utilisation.

Encore une fois, comme tu changes ta classe avant meme qu'elle ne soit
instanciée, ca permet de faire des petites choses en plus.....souvent
considérée comme de la "magie noire".


---OPQ et ses coquilles