On 9 avr, 01:01, Wykaaa <wyk...@yahoo.fr> wrote:
> bruno desthuilliers a écrit :> On 8 avr, 01:56, Wykaaa <wyk...@yahoo.fr> wrote:
> >> bruno desthuilliers a écrit :
>
> >>> On 7 avr, 21:12, Wykaaa <wyk...@yahoo.fr> wrote:
>
(snip)
>
> >> Et cette page, tu la connais (comparaison de langages dont Python, Ruby,
> >> PHP, C++, Java, etc.) ?http://www.jvoegele.com/software/langcomp.html
>
> > Le mec qui a pondu ça ferait mieux d'apprendre de quoi il cause, ça
> > lui éviterait de se ridiculiser.
>
> Je n'ai pas dit que cette page était bien. Outre qu'elle n'est pas à
> jour par rapport aux versions de langages, il y a de nombreuses
> approximation. Néanmoins c'est un effort méritant...
Pour moi, c'est un manque de l'effort minimum consistant à se
documenter avant de publier.
> Ok, allons-y:
>
> > "Object-Orientation Hybrid"
>
> > Toujours la même légende urbaine comme quoi Ruby serait "pur objet" et
> > pas Python, hein ? Bon, petit rappel, Python est orienté objet depuis
> > (au moins) la première release publique (la 0.91 si ma méoire est
> > bonne) en 1990. En l'état actuel, *tout* ce que tu peux trouver à la
> > droite d'une assignation est un objet. Les classes sont des objets,
> > les fonctions sont des objets, les modules sont des objets, même le
> > putain de byte-code des fonctions est exposé comme un objet. A part -
> > comme en Smalltalk - implémeter les messages comme des objets et les
> > structures de contrôle en tant que message, je vois mal comment faire
> > plus objet.
>
> Oui mais la plupart des auteurs s'accordent à dire que Python est
> hybride car il ne force pas le style objet.
Dans le sens où on n'est pas obligé de tout coller dans classes ?
Désolé, je ne vois pas en quoi cela constitue un "style objet".
Python ne force pas le style "orienté classe" de Java, mais la notion
de classe n'est pas nécessaire à (ni constitutive de) celle d'objet.
Self et Javascript sont des langages objets, et la notion de classe en
est absente.
Accessoirement, si Python est "hybride" pour cette raison, alors Ruby
l'est aussi - entre une fonction Python et une "methode" (hem)
implicitement assignée à un "objet global" essentiellement invisible,
franchement, c'est jouer sur les mots. Et que dire du code directement
au top-level - comme dans le snippet Ruby que tu citais ?
Que Ruby soit plus proche que Python de SmallTalk ne fait aucun doute,
et c'est le seul point sur lequel je lui concède un aspect plus 'pur'.
Par contre, je ne vois pas en quoi Java serait "plus pur objet" que
Python - par contre, je vois très bien en quoi il l'est nettement
moins (des types non objet dans un langage 'objet', là, oui, c'est
hybride).
> En première approche, on
> peut même dire que le style est plus fonctionnel qu'objet
Pour une définition 'a minima' de 'langage fonctionnel' comme 'langage
dans lequel les fonctions sont des aussi des données', Python est un
langage fonctionnel.
Dans la pratique, ce support vient tout simplement du fait que tout en
Python est objet - donc les fonctions aussi - et qu'on peut définir
ses propres types 'fonctionnels' (appelables). Il est d'ailleurs
courant d'utiliser cette deuxième solution plutôt qu'une fermeture dès
que la complexité de l'état à gérer devient non-triviale (ie: voir
l'objet 'partial' dans Python 2.5, et l'implémentation exemple en
Python donnée dans le PEP correspondant).
> (pour moi, cet
> aspect là, n'est pas un inconvénient)
Pour
> > "Higher Order Functions Lambda Expressions"
>
> > Ca veut dire quoi, ça ? L'instruction (très mal nommée) lambda génère
> > un objet fonction parfaitement ordinaire, ce n'est qu'un sucre
> > syntaxique pour des petites fonctions qui ne justifient pas une
> > définition séparée. Pour le reste, une fonction Python est un objet,
> > donc un citoyen parfaitement ordinaire.
>
> Mais ce n'est pas une critique !
Moi si, je critique. Je critique l'auteur de la page citée, en ce
qu'il implique que le support de HOF en Python se *limite* au
expressions lambda (accessoirement, en Python, lambda est une
instruction, mais bon, passons). Là encore, ça dénote une
méconnaissance du langage qui décridibilise totalement la page en
question.
> C'est très bien que Python supporte les fonctions d'ordre supérieur par
> des lambda expressions.
Python supporte les fonctions d'ordre supérieur, point, barre, et
l'instruction lambda n'a rien à voir avec ça. Python supporte
tellement les HOF d'ailleurs qu'il y a depuis la 2.4 une syntaxe
spéciale pour "décorer" une fonction avec une autre dès sa définition:
def trace(func):
def traced(*args, **kw):
print "func %s called with %s %s" % (func, str(args), kw)
result = func(*args, **kw)
print "result : %s" % str(result)
return result
return traced
@trace
def say_hello(who):
return "hello, %s" % who
say_hello('wykaaa')
>
> > "Garbage Collection Reference Counting"
>
> > Ca fait plusieurs années déjà que le comptage de référence est doublé
> > d'un GC capable de détecter les cycles.
>
> C'est dit dans le texte. le tableau est un peu réducteur. je cite (j'ai
> ajouté la flèche) :
Pas été voir plus bas.
> "Reference counting is the simplest scheme and involves the language
> keeping track of how many references there are to a particular object in
> memory, and deleting that object when that reference count becomes zero.
> This scheme, although it is simple and deterministic, is not without its
> drawbacks, the most important being its inability to handle cycles.
> Cycles occur when two objects reference each other, and thus there
> reference counts will never become zero even if neither object is
> referenced by any other part of the program.
>
> ==> This is the scheme that is utilized by Python and Visual Basic,
> although in the case of Python an extra step is taken to ensure that
> cycles are handled appropriately."
Son "extra step" s'appelle un garbage collector. Ne pas le mentionner
dans le tableau (qui est ce à quoi la plupart des lecteurs
s'arrêterons) est de la malhonnêté.
> > "Uniform Access No"
>
> > Si, et depuis toujours. Aux débuts en implémentant la méthode
> > __getattr__(self, name), et depuis plusieurs années via le protocole
> > descripteur - le plus souvent en utilisant le type 'property', qui
> > implémente ce protocole.
>
> tu veux dire comme ça ?
>
> class Foo(object):
> def __init__(self, x):
> self.setx(x)
>
> def getx(self):
> return self.__x
>
> def getx_times_5(self):
> return self.x*5
>
> x = property(getx, doc="getter for x")
> x_times_5 = property(getx_times_5, doc="getter for x, times 5")
Tu a oublié le setter dans ta définiton de x. Qui t'aurais évité un
appel explicite dans l'initialiseur.
class Foo(object):
def __init__(self, x):
self.x = x
@apply
def x():
def fget(self):
return self._x
def fset(self, val):
self._x = val
return property(**locals())
@property
def x_5_times:
return self._x * 5
> En Ruby :
Oui, je connais Ruby.
>
> D'un autre côté, en C++ ou en Java, si l'on veut respecter
> l'encapsulation (l'un des concepts majeur de l'objet),
pas seulement de l'objet
> on définira tous
> les attributs dans la partie privée d'une classe. Il y aura donc accès
> uniforme puisqu'un attribut de classe ne pourra jamais être accédé
> directement mais seulement par son "setter" et son "getter".
Yep. Mais on est obligé de définir des accesseurs pour tous les
attributs qu'on veut exposer, et de se taper systématiquement un appel
de méthode. Ca marche, certes, mais c'est un poil primitif.
>
>
> > "Class Variables / Methods No"
>
> > Les variables de classe ont toujours été supportées, les méthodes de
> > classe le sont depuis longtemps - si mon souvenir est bon depuis la
> > 2.0 ou 2.1, en tous cas une version antérieure à la rédaction de ce
> > document. A noter également que les classmethods Python, contrairement
> > aux méthodes "static" de Java, recoivent l'objet classe en premier
> > argument. Il existe aussi des staticmethods en Python, mais leur
> > emploi est rarissime puisque Python n'impose pas de tout caser dans
> > des classes, que ça ait un sens ou non.
>
> Ben voilà...
>
>
>
> > "Access Control Name Mangling"
>
> > Le name mangling (effectué sur les attributs préfixés d'un double
> > underscore) n'a pas pour vocation d'interdire l'accès à l'attribut,
> > mais de protéger un attribut essentiel d'une classe de base d'une
> > surcharge accidentelle. Le "contrôle d'accès" en Python se fait sur la
> > base d'une simple convention: un attribut préfixé d'un underscore
> > relève de l'implémentation, donc si vous y touchez, c'est votre
> > problème, on vous aura prévenu. Dans la pratique, ça marche
> > remarquablement bien.
>
> Oui mais l'encapsulation est un concept majeur dans l'approche objet et
et n'a qu'un rapport très lointain avec les restricteurs d'accès. Le
principe de l'encapsulation, c'est de 1/ regrouper et 2/ masquer les
détails d'implémentation, d'une part pour éviter au code utilisateur
d'avoir à s'en soucier, et d'autre part pour permettre de modifier
l'implémentation sans casser le code client.
> il est essentiel pour la fiabilité de la réutilisation et du
> développement par composants.
Un domaine dans lequel Python se démerde assez bien, merci.
> Dans tout le code objet que j'ai écrit et que j'écris, il n'y a JAMAIS
> d'attributs publics ni même "protected" dans les classes.
Moi si. Tout plein. Mais ce n'est pas un problème, parce que Python
supporte les attributs calculés, donc je peux remplacer un accès
direct par un accès calculé sans impact pour le code client.
> C'est aussi
> une règle que je regarde dans mes audits de code avec Logiscope (cette
> règle existe d'ailleurs "en dur" dans cette outil)
Python existe depuis 1990, il est utilisé par des dizaines de milliers
de développeurs de tous niveaux, et pas seulement sur des applications
triviales. L'absence de restriction d'accès (imposée par le langage,
j'entends) n'est manifestement pas un problème. Il y a là une évidence
empirique qu'il serait irrationnel de nier.
Accessoirement encore, il est possible de contourner les restrictions
d'accès en C++ (avec un define et une recompilation - implique d'avoir
accès au source, bien sûr) ou en Java (via la réflection).
> > Je note par contre que le garçon ne mentionne nulle part les
> > métaclasses...
>
> Oui c'est un manque dans le comparatif.
>
> > Si tu te bases sur des exemples et comparatifs pareils, pas de
> > surprise que tu ai une mauvaise image de Python. Franchement, tu
> > ferais mieux d'apprendre le langage et de te faire ta propre idée par
> > toi-même.
>
> Disons que je connais suffisamment le langage pour en parler
Vu les exemples que tu m'a sorti jusque là, tu m'excusera si je n'en
suis pas convaincu.
> et
> suffisamment l'analyse, la conception et la programmation objet pour
> effectivement voir que Python est laxiste vis-à-vis de cette approche,
Parce qu'il ne t'oblige pas à tout mettre dans des classes ?-)
> en particulier pour l'encapsulation.
en particulier pour les restricteurs d'accès - ce à quoi
l'encapsulation ne se résume pas.
Excuse-moi, mais vu le nombre de classe Java que j'ai vu où *tous* les
attributs étaient accessibles - via des accesseurs, certes, mais à ce
stade je ne vois pas ce que ça change -, et je ne te parles pas des
classes composées uniquement de staticmethods - bref, des fonctions
dans un module -, je n'achète pas tes arguments sur la nécessité
absolue des restrictions d'accès dans le langage. Soit le développeur
comprends l'encapsulation, et il n'a pas besoin qu'on lui force la
main, soit il ne la comprends pas (et ajoute des accesseurs pour tous
ses attributs sans exception), et ça ne sert à rien de toutes façons.
On en revient toujours au même point : le code est écrit par des
humains, et utilisé par des humains, et il n'y a pas solutions
techniques aux problèmes (fatigue, pression, distraction, manque
d'expérience, manque d'éducation, ou tout simplement bêtise) humains.
Aucune (je répète : aucune) technologie ne te mettra jamais à l'abri
d'une erreur humaine. cf cette bonne vieille Ariane. Je comprend -
particulièrement dans ton domaine - qu'on cherche à limiter les
risques d'erreurs (et, encore plus, leurs conséquences !), mais faire
d'une bonne pratique une règle idéologique, sans moi.
Y a plein de règles comme ça (les globales sont mauvaises, les goto
sont mauvais, les attributs accessibles sont mauvais etc) qui relèvent
de l'éducation, pas d'autre chose. Quand mon fils était petiot, je lui
interdisais de jouer avec les prises électriques, parce que lui
expliquer en quoi c'est dangereux n'aurait servi à rien. Maintenant,
ce n'est plus la peine de lui interdire, il est assez grand pour
savoir pourquoi c'est une mauvaise idée d'aller jouer avec une prise
électrique *à moins d'être sûr que le courant est coupé*. Et il sait
où est le disjoncteur. Est-ce que ça le mets pour toujours à l'abri
d'un accident suite à un moment d'inattention ? Non, bien sûr. Mais
là, tant qu'il y aura besoin d'installer ou de réparer des prises
électriques, le risque existera. Le seul moyen absolument efficace
pour ne pas risquer de mourir, c'est d'être mort. Et le seul code
garanti sans bug, c'est pas de code. Ce qui pour moi est une raison
majeure pour éviter le code inutile, soit dis au passage.
> Je suis désolé de te le dire...
> Mais je le dis sans polémique.
pareil !-)
> D'ailleurs l'encapsulation (aui existe indépendamment de l'objet) est
> bien plus importante que l'héritage,
Tu prêches un converti. Mais pour une définition légèrement différente
d'encapsulation !-)
> même dans l'approche objet, car
> elle permet (utilisée conjointement avec les types paramétrés) la
> réutilisation à grande échelle alors que l'héritage "n'adresse que" la
> factorisation du code. Il le rend cependant plus maintenable puisque,
> via le polymorphisme d'héritage, il permet de se dispenser des "switch".
L'héritage (d'implémentation ou d'interface) ne conditionne le
dispatch polymorphisme des messages *que* dans les langages à typage
statique.
> La chasse aux switchs est à la programmation objet ce que la chasse aux
> gotos est à la programmation structurée.
Là encore, si tu veux, je ne t'ai pas attendu pour m'en rendre
compte !-)
Par contre, le "dispatch simple" de la plupart des modèles objet reste
très limité AMHA - à preuve, l'invention du pattern visiteur. CLOS,
avec son multidispatch, offre bien plus de possibilité - au prix, bien
sûr, d'une complexité intrinsèque plus grande, et vu la difficulté
qu'ont encore pas mal de développeurs à comprendre le single
dispatch... Enfin bon, c'est un autre troll^M^débat...
> Sans rancune
Rancune ? Pourquoi donc ?
Tu sais, ce n'est pas parce que je défends mes points de vues avec
conviction que j'attends des autres qu'ils les partagent, hein.
<troll>Enfin, pas immédiatement !-)))</troll>