Bon, comme d'autres l'ont fait remarquer ta question ne distingue pas proprement (a) classes et instances, (b) sous-classes et membres. Comme ils ont rectifié dans le sens où ton intention porte sur les instances, je voudrais juste te faire observer à toutes fins utiles qu'on peut aussi écrire
class B : valeur = 'test B'
class A : valeur = 'test A' b = B
et accéder de n'importe où à A.valeur, B.valeur, A.b et A.b.valeur
alors ce self.valeur dans la definition de classe ne sert à rien ?
s/definition de classe/initialiseur/
Bien que techniquement juste, le post de Boris risque AMHA d'induire pas mal de débutants en erreur. Dans l'exemple qu'il donne, ce sont des attributs de classe - donc partagés par toutes les instances de la classe. Ce qui, bien que parfois utiles, n'est généralement pas ce qu'on cherche en OO, puisque le but est que chaque instance gère son propre état.
class A: def __init__(self): self.valeur="test 1" # ca equivaut à ??? valeur="test 1"
Non, pas du tout et en aucun cas. Et ça ne correspond pas non plus a ce qu'a posté Boris. La première ligne définit un attribut d'instance, la seconde une variable locale.
Globalement, et en simplifiant outrageusement: en Python (comme dans pas mal de langages objets dynamiques), un objet est une sorte de super-dictionnaire. On peut (sauf cas particuliers) lui ajouter/supprimer dynamiquement des attributs. Une classe est un objet aussi, donc ça marche pareil. Accessoirement, la classe d'un objet est un de ses attributs, et on peut changer cette classe à l'exécution (bien que ce soit généralement une mauvaise idée...).
Bien.
Maintenant, une des différences majeures entre un objet et un simple dictionnaire concerne les règles de résolution d'attribut (in english: lookup). Dans le cas d'un objet, un attribut est d'abord recherché dans les variables d'instance (stockés dans l'attribut __dict__ de l'instance). Si cette recherche échoue, l'attribut est recherché dans la classes (stockée dans l'attribut __class__), puis si besoin dans les superclasses (accessibles par l'attribut __mro__ de l'objet classe). Si l'attribut n'est toujours pas trouvé mais que la classe (ou une superclasse) définit une fonction __getattr__, celle ci sera appelée. Sinon, une exception AttributeError sera levée.
Petit rappel au passage: puisque tout est objet, un attribut peut parfaitement être une fonction (instance de la classe function...).
Il existe un cas particulier: le protocole "descripteur" (explication plus bas). Si un attribut implémente ce protocole *et* que c'est un attribut de classe, alors ce protocole est invoqué, et c'est l'objet retourné par cette invocation qui sera utilisé comme "valeur" de l'attribut.
Ce protocole "descripteur" consiste en au minimum une méthode __get__(self, obj, cls), et optionnellement une méthode __set__(self, obj, value) et une méthode __del__(self, obj). Dans le cas courant (attribut recherché sur l'instance), __get__ est donc appelé avec self = l'attribut réel, obj = l'instance sur laquelle l'attribut est recherché, et cls = la classe de obj. Si l'attribut est recherché directement sur la classe, bien évidemment, obj est valorisé à None.
Il y a deux applications connues de ce mécanisme. La première est évidente - que ce qui ont déjà reconnu les attributs calculés (alias 'property') - lèvent le doigt. La seconde l'est moins, alors qu'elle est la plus utilisée : les méthodes. La classe function implémente effectivement le protocole descripteur, de sorte que quand une fonction est un attribut d'une classe, et que cet attribut est recherché sur une instance, la méthode __get__ de la fonction retourne un objet method, lequel n'est qu'un enrobage très simple autour de la fonction, l'instance et la classe de l'instance (bin oui: les trois arguments passés à __get__....). En (très) simplifié, voici à quoi ressemble l'affaire:
class UnboundMethod(object): def __init__(self, func, cls): self.im_func = func self.im_class = cls def __call__(self, obj, *args, **kw): if not isinstance(obj, self.im_class): raise TypeError("message bien connu ici") return self.im_func(obj, *args, **kw)
class function(object): # on passe toute le reste de la plomberie def __get__(self, obj, cls): if obj is None: return UnboundMethod(self, cls) else: return BoundMethod(self, obj)
Bien bien... Maintenant, un petit tour du côté de l'instruction 'class'. Tous les noms définis dans le corps de cette instruction - par une instruction d'assignation (name = val) ou par une instruction 'def' - deviennent des attributs de la classe. Mais, ce détail mis à part, ils ne sont pas différents de ce qu'ils seraient s'ils étaient définis en dehors du corps de la classe, puis assigné à la classe après coup. Ce qui d'ailleurs se vérifie aisément:
Toto.tutu = tutu Toto.tata = 42 Toto.tata # la classe int n'implémente pas le protocol descripteur 42
Toto.tutu # la classe fonction l'implémente, cf ci-avant <unbound method Toto.tutu>
# on peut retrouver la fonction tutu de deux façons: # soit dans le __dict__ de Toto: Toto.__dict__['tutu'] <function tutu at 0x4032f304>
Toto.__dict__['tutu'] is tutu True
# soit comme attribut im_func de l'objet method: Toto.tutu.im_func <function tutu at 0x4032f304>
# et on peut vérifier que les objets method sont bien créés dynamiquement lors de l'accès à l'attribut: m1 = Toto.tutu m2 = Toto.tutu m1 is m2 False
# et maintenant, le cas courant: t = Toto() t.tutu <bound method Toto.tutu of <__main__.Toto object at 0x4033480c>>
t.tutu("yadda") dans fonction tutu : obj=<__main__.Toto object at 0x4033480c>, val=yadda
C'est bien joli, tout ça, mais pour en venir à quoi me direz vous ? Essentiellement, à expliquer pourquoi, dans une "méthode", l'utilisation de "self" (ou quelque soit le nom utilisé) est impératif pour accéder à l'instance. Dans la pratique:
class A(object): val = 42
revient strictement au même que:
class AA(object): pass AA.val = 42
puisqu'une classe est un objet.
De même:
class B(object): def __init__(self): self.val = 42
b = B()
revient au même que:
class B(object): pass
def initB(b): b.val = 42
B.__init__ = initB
b = B()
qui revient au même que
class C(object): pass
def initC(c): c.val = 42
c = C() initC(c)
qui (ouf) revient au même que
class D(object): pass
d = D() d.val = 42
dans ce cas je me suis bien usé les doigts pour rien ;)
Bin non. Tu a fais ce qu'il fallait.
HTH
Bon, comme d'autres l'ont fait remarquer ta question ne distingue pas
proprement (a) classes et instances, (b) sous-classes et membres.
Comme ils ont rectifié dans le sens où ton intention porte sur les
instances, je voudrais juste te faire observer à toutes fins utiles
qu'on peut aussi écrire
class B :
valeur = 'test B'
class A :
valeur = 'test A'
b = B
et accéder de n'importe où à A.valeur, B.valeur, A.b et A.b.valeur
alors ce self.valeur dans la definition de classe ne sert à rien ?
s/definition de classe/initialiseur/
Bien que techniquement juste, le post de Boris risque AMHA d'induire pas
mal de débutants en erreur. Dans l'exemple qu'il donne, ce sont des
attributs de classe - donc partagés par toutes les instances de la
classe. Ce qui, bien que parfois utiles, n'est généralement pas ce qu'on
cherche en OO, puisque le but est que chaque instance gère son propre
état.
class A:
def __init__(self):
self.valeur="test 1"
# ca equivaut à ???
valeur="test 1"
Non, pas du tout et en aucun cas. Et ça ne correspond pas non plus a ce
qu'a posté Boris. La première ligne définit un attribut d'instance, la
seconde une variable locale.
Globalement, et en simplifiant outrageusement: en Python (comme dans pas
mal de langages objets dynamiques), un objet est une sorte de
super-dictionnaire. On peut (sauf cas particuliers) lui
ajouter/supprimer dynamiquement des attributs. Une classe est un objet
aussi, donc ça marche pareil. Accessoirement, la classe d'un objet est
un de ses attributs, et on peut changer cette classe à l'exécution (bien
que ce soit généralement une mauvaise idée...).
Bien.
Maintenant, une des différences majeures entre un objet et un simple
dictionnaire concerne les règles de résolution d'attribut (in english:
lookup). Dans le cas d'un objet, un attribut est d'abord recherché dans
les variables d'instance (stockés dans l'attribut __dict__ de
l'instance). Si cette recherche échoue, l'attribut est recherché dans la
classes (stockée dans l'attribut __class__), puis si besoin dans les
superclasses (accessibles par l'attribut __mro__ de l'objet classe). Si
l'attribut n'est toujours pas trouvé mais que la classe (ou une
superclasse) définit une fonction __getattr__, celle ci sera appelée.
Sinon, une exception AttributeError sera levée.
Petit rappel au passage: puisque tout est objet, un attribut peut
parfaitement être une fonction (instance de la classe function...).
Il existe un cas particulier: le protocole "descripteur" (explication
plus bas). Si un attribut implémente ce protocole *et* que c'est un
attribut de classe, alors ce protocole est invoqué, et c'est l'objet
retourné par cette invocation qui sera utilisé comme "valeur" de
l'attribut.
Ce protocole "descripteur" consiste en au minimum une méthode
__get__(self, obj, cls), et optionnellement une méthode __set__(self,
obj, value) et une méthode __del__(self, obj). Dans le cas courant
(attribut recherché sur l'instance), __get__ est donc appelé avec self =
l'attribut réel, obj = l'instance sur laquelle l'attribut est
recherché, et cls = la classe de obj. Si l'attribut est recherché
directement sur la classe, bien évidemment, obj est valorisé à None.
Il y a deux applications connues de ce mécanisme. La première est
évidente - que ce qui ont déjà reconnu les attributs calculés (alias
'property') - lèvent le doigt. La seconde l'est moins, alors qu'elle est
la plus utilisée : les méthodes. La classe function implémente
effectivement le protocole descripteur, de sorte que quand une fonction
est un attribut d'une classe, et que cet attribut est recherché sur une
instance, la méthode __get__ de la fonction retourne un objet method,
lequel n'est qu'un enrobage très simple autour de la fonction,
l'instance et la classe de l'instance (bin oui: les trois arguments
passés à __get__....). En (très) simplifié, voici à quoi ressemble
l'affaire:
class UnboundMethod(object):
def __init__(self, func, cls):
self.im_func = func
self.im_class = cls
def __call__(self, obj, *args, **kw):
if not isinstance(obj, self.im_class):
raise TypeError("message bien connu ici")
return self.im_func(obj, *args, **kw)
class function(object):
# on passe toute le reste de la plomberie
def __get__(self, obj, cls):
if obj is None:
return UnboundMethod(self, cls)
else:
return BoundMethod(self, obj)
Bien bien... Maintenant, un petit tour du côté de l'instruction 'class'.
Tous les noms définis dans le corps de cette instruction - par une
instruction d'assignation (name = val) ou par une instruction 'def' -
deviennent des attributs de la classe. Mais, ce détail mis à part, ils
ne sont pas différents de ce qu'ils seraient s'ils étaient définis en
dehors du corps de la classe, puis assigné à la classe après coup. Ce
qui d'ailleurs se vérifie aisément:
Toto.tutu = tutu
Toto.tata = 42
Toto.tata # la classe int n'implémente pas le protocol descripteur
42
Toto.tutu # la classe fonction l'implémente, cf ci-avant
<unbound method Toto.tutu>
# on peut retrouver la fonction tutu de deux façons:
# soit dans le __dict__ de Toto:
Toto.__dict__['tutu']
<function tutu at 0x4032f304>
Toto.__dict__['tutu'] is tutu
True
# soit comme attribut im_func de l'objet method:
Toto.tutu.im_func
<function tutu at 0x4032f304>
# et on peut vérifier que les objets method sont bien
créés dynamiquement lors de l'accès à l'attribut:
m1 = Toto.tutu
m2 = Toto.tutu
m1 is m2
False
# et maintenant, le cas courant:
t = Toto()
t.tutu
<bound method Toto.tutu of <__main__.Toto object at 0x4033480c>>
t.tutu("yadda")
dans fonction tutu : obj=<__main__.Toto object at 0x4033480c>, val=yadda
C'est bien joli, tout ça, mais pour en venir à quoi me direz vous ?
Essentiellement, à expliquer pourquoi, dans une "méthode", l'utilisation
de "self" (ou quelque soit le nom utilisé) est impératif pour accéder à
l'instance. Dans la pratique:
class A(object):
val = 42
revient strictement au même que:
class AA(object):
pass
AA.val = 42
puisqu'une classe est un objet.
De même:
class B(object):
def __init__(self):
self.val = 42
b = B()
revient au même que:
class B(object):
pass
def initB(b):
b.val = 42
B.__init__ = initB
b = B()
qui revient au même que
class C(object):
pass
def initC(c):
c.val = 42
c = C()
initC(c)
qui (ouf) revient au même que
class D(object):
pass
d = D()
d.val = 42
dans ce cas je me suis bien usé les doigts pour rien ;)
Bon, comme d'autres l'ont fait remarquer ta question ne distingue pas proprement (a) classes et instances, (b) sous-classes et membres. Comme ils ont rectifié dans le sens où ton intention porte sur les instances, je voudrais juste te faire observer à toutes fins utiles qu'on peut aussi écrire
class B : valeur = 'test B'
class A : valeur = 'test A' b = B
et accéder de n'importe où à A.valeur, B.valeur, A.b et A.b.valeur
alors ce self.valeur dans la definition de classe ne sert à rien ?
s/definition de classe/initialiseur/
Bien que techniquement juste, le post de Boris risque AMHA d'induire pas mal de débutants en erreur. Dans l'exemple qu'il donne, ce sont des attributs de classe - donc partagés par toutes les instances de la classe. Ce qui, bien que parfois utiles, n'est généralement pas ce qu'on cherche en OO, puisque le but est que chaque instance gère son propre état.
class A: def __init__(self): self.valeur="test 1" # ca equivaut à ??? valeur="test 1"
Non, pas du tout et en aucun cas. Et ça ne correspond pas non plus a ce qu'a posté Boris. La première ligne définit un attribut d'instance, la seconde une variable locale.
Globalement, et en simplifiant outrageusement: en Python (comme dans pas mal de langages objets dynamiques), un objet est une sorte de super-dictionnaire. On peut (sauf cas particuliers) lui ajouter/supprimer dynamiquement des attributs. Une classe est un objet aussi, donc ça marche pareil. Accessoirement, la classe d'un objet est un de ses attributs, et on peut changer cette classe à l'exécution (bien que ce soit généralement une mauvaise idée...).
Bien.
Maintenant, une des différences majeures entre un objet et un simple dictionnaire concerne les règles de résolution d'attribut (in english: lookup). Dans le cas d'un objet, un attribut est d'abord recherché dans les variables d'instance (stockés dans l'attribut __dict__ de l'instance). Si cette recherche échoue, l'attribut est recherché dans la classes (stockée dans l'attribut __class__), puis si besoin dans les superclasses (accessibles par l'attribut __mro__ de l'objet classe). Si l'attribut n'est toujours pas trouvé mais que la classe (ou une superclasse) définit une fonction __getattr__, celle ci sera appelée. Sinon, une exception AttributeError sera levée.
Petit rappel au passage: puisque tout est objet, un attribut peut parfaitement être une fonction (instance de la classe function...).
Il existe un cas particulier: le protocole "descripteur" (explication plus bas). Si un attribut implémente ce protocole *et* que c'est un attribut de classe, alors ce protocole est invoqué, et c'est l'objet retourné par cette invocation qui sera utilisé comme "valeur" de l'attribut.
Ce protocole "descripteur" consiste en au minimum une méthode __get__(self, obj, cls), et optionnellement une méthode __set__(self, obj, value) et une méthode __del__(self, obj). Dans le cas courant (attribut recherché sur l'instance), __get__ est donc appelé avec self = l'attribut réel, obj = l'instance sur laquelle l'attribut est recherché, et cls = la classe de obj. Si l'attribut est recherché directement sur la classe, bien évidemment, obj est valorisé à None.
Il y a deux applications connues de ce mécanisme. La première est évidente - que ce qui ont déjà reconnu les attributs calculés (alias 'property') - lèvent le doigt. La seconde l'est moins, alors qu'elle est la plus utilisée : les méthodes. La classe function implémente effectivement le protocole descripteur, de sorte que quand une fonction est un attribut d'une classe, et que cet attribut est recherché sur une instance, la méthode __get__ de la fonction retourne un objet method, lequel n'est qu'un enrobage très simple autour de la fonction, l'instance et la classe de l'instance (bin oui: les trois arguments passés à __get__....). En (très) simplifié, voici à quoi ressemble l'affaire:
class UnboundMethod(object): def __init__(self, func, cls): self.im_func = func self.im_class = cls def __call__(self, obj, *args, **kw): if not isinstance(obj, self.im_class): raise TypeError("message bien connu ici") return self.im_func(obj, *args, **kw)
class function(object): # on passe toute le reste de la plomberie def __get__(self, obj, cls): if obj is None: return UnboundMethod(self, cls) else: return BoundMethod(self, obj)
Bien bien... Maintenant, un petit tour du côté de l'instruction 'class'. Tous les noms définis dans le corps de cette instruction - par une instruction d'assignation (name = val) ou par une instruction 'def' - deviennent des attributs de la classe. Mais, ce détail mis à part, ils ne sont pas différents de ce qu'ils seraient s'ils étaient définis en dehors du corps de la classe, puis assigné à la classe après coup. Ce qui d'ailleurs se vérifie aisément:
Toto.tutu = tutu Toto.tata = 42 Toto.tata # la classe int n'implémente pas le protocol descripteur 42
Toto.tutu # la classe fonction l'implémente, cf ci-avant <unbound method Toto.tutu>
# on peut retrouver la fonction tutu de deux façons: # soit dans le __dict__ de Toto: Toto.__dict__['tutu'] <function tutu at 0x4032f304>
Toto.__dict__['tutu'] is tutu True
# soit comme attribut im_func de l'objet method: Toto.tutu.im_func <function tutu at 0x4032f304>
# et on peut vérifier que les objets method sont bien créés dynamiquement lors de l'accès à l'attribut: m1 = Toto.tutu m2 = Toto.tutu m1 is m2 False
# et maintenant, le cas courant: t = Toto() t.tutu <bound method Toto.tutu of <__main__.Toto object at 0x4033480c>>
t.tutu("yadda") dans fonction tutu : obj=<__main__.Toto object at 0x4033480c>, val=yadda
C'est bien joli, tout ça, mais pour en venir à quoi me direz vous ? Essentiellement, à expliquer pourquoi, dans une "méthode", l'utilisation de "self" (ou quelque soit le nom utilisé) est impératif pour accéder à l'instance. Dans la pratique:
class A(object): val = 42
revient strictement au même que:
class AA(object): pass AA.val = 42
puisqu'une classe est un objet.
De même:
class B(object): def __init__(self): self.val = 42
b = B()
revient au même que:
class B(object): pass
def initB(b): b.val = 42
B.__init__ = initB
b = B()
qui revient au même que
class C(object): pass
def initC(c): c.val = 42
c = C() initC(c)
qui (ouf) revient au même que
class D(object): pass
d = D() d.val = 42
dans ce cas je me suis bien usé les doigts pour rien ;)
Bin non. Tu a fais ce qu'il fallait.
HTH
JB
Mmm... Et tu a combien d'instances différentes de MonServeur ? Je pose la question parce qu'à vu de nez, j'aurais tendance à penser qu'une classe n'est pas forcément nécessaire... Les modules Python sont naturellement des Singletons, donc un bon moyen de partager certaines ressources entre plusieurs objets. Les classes ne sont utiles que quand on a besoin de plusieurs instances simultanées gérant chacune leur état propre.
Et bien en effet, je n'aurai qu'un serveur qui tourne par machine... donc il vaut mieux faire un module qu'une classe ?
Merci Bruno pour tous les conseils, infos , idées...
Julien
Mmm... Et tu a combien d'instances différentes de MonServeur ? Je pose
la question parce qu'à vu de nez, j'aurais tendance à penser qu'une
classe n'est pas forcément nécessaire... Les modules Python sont
naturellement des Singletons, donc un bon moyen de partager certaines
ressources entre plusieurs objets. Les classes ne sont utiles que quand
on a besoin de plusieurs instances simultanées gérant chacune leur état
propre.
Et bien en effet, je n'aurai qu'un serveur qui tourne par machine...
donc il vaut mieux faire un module qu'une classe ?
Merci Bruno pour tous les conseils, infos , idées...
Mmm... Et tu a combien d'instances différentes de MonServeur ? Je pose la question parce qu'à vu de nez, j'aurais tendance à penser qu'une classe n'est pas forcément nécessaire... Les modules Python sont naturellement des Singletons, donc un bon moyen de partager certaines ressources entre plusieurs objets. Les classes ne sont utiles que quand on a besoin de plusieurs instances simultanées gérant chacune leur état propre.
Et bien en effet, je n'aurai qu'un serveur qui tourne par machine... donc il vaut mieux faire un module qu'une classe ?
Merci Bruno pour tous les conseils, infos , idées...
Julien
Bruno Desthuilliers
Mmm... Et tu a combien d'instances différentes de MonServeur ? Je pose la question parce qu'à vu de nez, j'aurais tendance à penser qu'une classe n'est pas forcément nécessaire... Les modules Python sont naturellement des Singletons, donc un bon moyen de partager certaines ressources entre plusieurs objets. Les classes ne sont utiles que quand on a besoin de plusieurs instances simultanées gérant chacune leur état propre.
Et bien en effet, je n'aurai qu'un serveur qui tourne par machine... donc il vaut mieux faire un module qu'une classe ?
Si ta classe est de fait conceptuellement un singleton, alors effectivement autant faire simple[1]. Et n'oublie pas qu'un module est un objet aussi... Tu a donc la possibilité soit de rendre ton module MonServeur directement accessible via un import, soit de le passer en paramètre à un initialiseur là où tu veux garder un bon découplage.
[1] Contrairement à ce qu'un certain discours tend à faire croire, OO signifie 'orienté objet', pas 'orienté classe', et les classes ne sont *pas* la notion centrale de la POO.
Mes deux centimes...
Mmm... Et tu a combien d'instances différentes de MonServeur ? Je pose
la question parce qu'à vu de nez, j'aurais tendance à penser qu'une
classe n'est pas forcément nécessaire... Les modules Python sont
naturellement des Singletons, donc un bon moyen de partager certaines
ressources entre plusieurs objets. Les classes ne sont utiles que
quand on a besoin de plusieurs instances simultanées gérant chacune
leur état propre.
Et bien en effet, je n'aurai qu'un serveur qui tourne par machine...
donc il vaut mieux faire un module qu'une classe ?
Si ta classe est de fait conceptuellement un singleton, alors
effectivement autant faire simple[1]. Et n'oublie pas qu'un module est
un objet aussi... Tu a donc la possibilité soit de rendre ton module
MonServeur directement accessible via un import, soit de le passer en
paramètre à un initialiseur là où tu veux garder un bon découplage.
[1] Contrairement à ce qu'un certain discours tend à faire croire, OO
signifie 'orienté objet', pas 'orienté classe', et les classes ne sont
*pas* la notion centrale de la POO.
Mmm... Et tu a combien d'instances différentes de MonServeur ? Je pose la question parce qu'à vu de nez, j'aurais tendance à penser qu'une classe n'est pas forcément nécessaire... Les modules Python sont naturellement des Singletons, donc un bon moyen de partager certaines ressources entre plusieurs objets. Les classes ne sont utiles que quand on a besoin de plusieurs instances simultanées gérant chacune leur état propre.
Et bien en effet, je n'aurai qu'un serveur qui tourne par machine... donc il vaut mieux faire un module qu'une classe ?
Si ta classe est de fait conceptuellement un singleton, alors effectivement autant faire simple[1]. Et n'oublie pas qu'un module est un objet aussi... Tu a donc la possibilité soit de rendre ton module MonServeur directement accessible via un import, soit de le passer en paramètre à un initialiseur là où tu veux garder un bon découplage.
[1] Contrairement à ce qu'un certain discours tend à faire croire, OO signifie 'orienté objet', pas 'orienté classe', et les classes ne sont *pas* la notion centrale de la POO.
Mes deux centimes...
Méta-MCI \(MVP\)
Bonjour !
OO signifie 'orienté objet', pas 'orienté classe'
Tu fais bien de le rappeler. Car il existe, aussi, des langages "Orientés Objet" par prototypage, comme Javascript, qui n'utilisent pas les classes. Ce qui n'empêche pas certains auteurs d'utiliser ce mot, sans doute pour mieux se faire comprendre.
@+
Michel Claveau
PS : certaines familles de langages se disent orientés objet, mais je ne suis pas sûr ; je pense, entre autre, à la programmation orientée aspect, à la programmation par contrats, à la programmation par messaging. Sans compter que certains peuvent être multi-paradigmes.
Bonjour !
OO signifie 'orienté objet', pas 'orienté classe'
Tu fais bien de le rappeler. Car il existe, aussi, des langages
"Orientés Objet" par prototypage, comme Javascript, qui n'utilisent pas
les classes.
Ce qui n'empêche pas certains auteurs d'utiliser ce mot, sans doute pour
mieux se faire comprendre.
@+
Michel Claveau
PS : certaines familles de langages se disent orientés objet, mais je ne
suis pas sûr ; je pense, entre autre, à la programmation orientée
aspect, à la programmation par contrats, à la programmation par
messaging. Sans compter que certains peuvent être multi-paradigmes.
Tu fais bien de le rappeler. Car il existe, aussi, des langages "Orientés Objet" par prototypage, comme Javascript, qui n'utilisent pas les classes. Ce qui n'empêche pas certains auteurs d'utiliser ce mot, sans doute pour mieux se faire comprendre.
@+
Michel Claveau
PS : certaines familles de langages se disent orientés objet, mais je ne suis pas sûr ; je pense, entre autre, à la programmation orientée aspect, à la programmation par contrats, à la programmation par messaging. Sans compter que certains peuvent être multi-paradigmes.
Bruno Desthuilliers
Bonjour !
OO signifie 'orienté objet', pas 'orienté classe'
Tu fais bien de le rappeler. Car il existe, aussi, des langages "Orientés Objet" par prototypage, comme Javascript, qui n'utilisent pas les classes.
Pour ce que ça vaut, le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Bonjour !
OO signifie 'orienté objet', pas 'orienté classe'
Tu fais bien de le rappeler. Car il existe, aussi, des langages
"Orientés Objet" par prototypage, comme Javascript, qui n'utilisent pas
les classes.
Pour ce que ça vaut, le modèle objet de Python est plus proche de celui
de javascript que de celui de Java...
Tu fais bien de le rappeler. Car il existe, aussi, des langages "Orientés Objet" par prototypage, comme Javascript, qui n'utilisent pas les classes.
Pour ce que ça vaut, le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Méta-MCI \(MVP\)
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée ! Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit en java comportait cinq lignes, et ne servait qu'à vérifier la possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que
de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée !
Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit
en java comportait cinq lignes, et ne servait qu'à vérifier la
possibilité d'appeler un serveur COM (en Python).
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée ! Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit en java comportait cinq lignes, et ne servait qu'à vérifier la possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
BertrandB
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée ! Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit en java comportait cinq lignes, et ne servait qu'à vérifier la possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Non dans le contexte du texte d'origine ce n'étais pas osé. En
javascript il est equivalent d'écrire :
object.property object["property"]
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que
de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée !
Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit
en java comportait cinq lignes, et ne servait qu'à vérifier la
possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Non dans le contexte du texte d'origine ce n'étais pas osé. En
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée ! Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit en java comportait cinq lignes, et ne servait qu'à vérifier la possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Non dans le contexte du texte d'origine ce n'étais pas osé. En
javascript il est equivalent d'écrire :
object.property object["property"]
Bruno Desthuilliers
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée ! Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit en java comportait cinq lignes, et ne servait qu'à vérifier la possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Non dans le contexte du texte d'origine ce n'étais pas osé. En
javascript il est equivalent d'écrire :
object.property object["property"]
Ce n'est pas seulement à ça que je pensais (même si effectivement Javascript et Python utilisent tous deux une table de hachage comme base pour les objets). En Python, la "classe" d'un objet est elle-même un objet sur lequel l'instance a une référence (modifiable à l'exécution), et dans laquelle sont recherchés les attributs non trouvés dans l'instance. Bref, une classe Python est techniquement très proche d'un prototype....
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que
de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée !
Mais, je te crois volontiers, vu que, le seul code que j'ai jamais
écrit en java comportait cinq lignes, et ne servait qu'à vérifier la
possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Non dans le contexte du texte d'origine ce n'étais pas osé. En
javascript il est equivalent d'écrire :
object.property
object["property"]
Ce n'est pas seulement à ça que je pensais (même si effectivement
Javascript et Python utilisent tous deux une table de hachage comme base
pour les objets). En Python, la "classe" d'un objet est elle-même un
objet sur lequel l'instance a une référence (modifiable à l'exécution),
et dans laquelle sont recherchés les attributs non trouvés dans
l'instance. Bref, une classe Python est techniquement très proche d'un
prototype....
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée ! Mais, je te crois volontiers, vu que, le seul code que j'ai jamais écrit en java comportait cinq lignes, et ne servait qu'à vérifier la possibilité d'appeler un serveur COM (en Python).
@+
Michel Claveau
Non dans le contexte du texte d'origine ce n'étais pas osé. En
javascript il est equivalent d'écrire :
object.property object["property"]
Ce n'est pas seulement à ça que je pensais (même si effectivement Javascript et Python utilisent tous deux une table de hachage comme base pour les objets). En Python, la "classe" d'un objet est elle-même un objet sur lequel l'instance a une référence (modifiable à l'exécution), et dans laquelle sont recherchés les attributs non trouvés dans l'instance. Bref, une classe Python est techniquement très proche d'un prototype....
Bruno Desthuilliers
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée !
???
Je ne vois pas où est l'"audace" là-dedans. Il suffit d'étudier les modèles objets de ces trois langages pour constater l'évidence.
Bonsoir !
le modèle objet de Python est plus proche de celui de javascript que
de celui de Java...
Quelle audace, d'énoncer une proposition aussi engagée !
???
Je ne vois pas où est l'"audace" là-dedans. Il suffit d'étudier les
modèles objets de ces trois langages pour constater l'évidence.