OVH Cloud OVH Cloud

types vs classes

15 réponses
Avatar
Eric Jacoboni
Bonjour,

Il y a un truc que j'ai du mal à saisir en Python : parfois, il y a
des types (date, par exemple), parfois il y a des classes (Decimal,
par exemple). On les repère par leur casse, très bien.

Mais je n'arrive pas à comprendre la logique/cohérence là-dedans : je
veux dire, pourquoi date n'est pas une classe ? c'est quand même
typiquement une abstraction au même sens que Decimal, non ? (je parle
de date, et de Decimal mais il y a une brouettée d'autres exemples).

Si on pouvait m'expliquer la justification de tout ça, je suis preneur
parce que, là, je trouve ça lourd d'être obligé de systématiquement me
poser la question à chaque fois que j'ai besoin d'un objet.
--
Eric Jacoboni, ne il y a 1436746622 secondes

10 réponses

1 2
Avatar
Laurent Pointal
Eric Jacoboni wrote:
Bonjour,

Il y a un truc que j'ai du mal à saisir en Python : parfois, il y a
des types (date, par exemple), parfois il y a des classes (Decimal,
par exemple). On les repère par leur casse, très bien.

Mais je n'arrive pas à comprendre la logique/cohérence là-dedans : je
veux dire, pourquoi date n'est pas une classe ? c'est quand même
typiquement une abstraction au même sens que Decimal, non ? (je parle
de date, et de Decimal mais il y a une brouettée d'autres exemples).

Si on pouvait m'expliquer la justification de tout ça, je suis preneur
parce que, là, je trouve ça lourd d'être obligé de systématiquement me
poser la question à chaque fois que j'ai besoin d'un objet.


Je dirais que c'est historique.

Les types de base (qui sont des classes!) sont en minuscules.
Les type définis dans des modules tiers utilisent en général des
majuscules au début des mots (mais comme toute règle générale, on doit
sûrement pouvoir y trouver de exceptions).

Certains types étaient précédement dispos dans des modules séparés (ex.
Set, FrozenSet) et sont passés en minuscules lorsqu'ils ont été passé en
builtins (set, frozenset en 2.4).

Pour la date, il peut y avoir une explication qu'il n'y ait pas de
builtin la représentant: on utilise généralement le format unix (nb de
secondes depuis le 1/1/70) quise code simplement dans un entier, et
lorsque l'on a besoin de qq chose de plus costaud il y a des modules
tiers comme mxDateTime qui gèrent les différents calendriers & Co.

Mes deux cents.

A+

Laurent.

Avatar
Eric Jacoboni
Laurent Pointal writes:

Je dirais que c'est historique.


C'est ce je craignais... mais si c'est historique, pourquoi les
évolutions du langage n'ont pas intégré de wrappers pour unifier
l'existant ?

Les types de base (qui sont des classes!) sont en minuscules.
Les type définis dans des modules tiers utilisent en général des
majuscules au début des mots (mais comme toute règle générale, on doit
sûrement pouvoir y trouver de exceptions).

Certains types étaient précédement dispos dans des modules séparés (ex.
Set, FrozenSet) et sont passés en minuscules lorsqu'ils ont été passé en
builtins (set, frozenset en 2.4).


Oui, mais si c'est ça, la sacro-sainte « intuitivité » du langage un
prend un sacré coup sur le museau parce que s'il faut se rappeler des
orthographes particulières de chaque classe, c'est quand même un peu
moyen pour un langage moderne. J'ai même beaucoup de mal à croire
qu'il en soit ainsi, d'ailleurs : C, C++, Java etc. n'ayant pas ce
défaut, je comprendrais mal que Python l'ait.

Avatar
Laurent Pointal
Eric Jacoboni wrote:

Oui, mais si c'est ça, la sacro-sainte « intuitivité » du langage un
prend un sacré coup sur le museau parce que s'il faut se rappeler des
orthographes particulières de chaque classe, c'est quand même un peu
moyen pour un langage moderne. J'ai même beaucoup de mal à croire
qu'il en soit ainsi, d'ailleurs : C, C++, Java etc. n'ayant pas ce
défaut, je comprendrais mal que Python l'ait.


Ils ont aussi ce défaut.

Les types de base de C++ sont très réduits, tout le reste est dispo sous
forme de classes qui peuvent très bien ne pas être disponibles (et qui
ne l'étaient pas il y a qq années). La STL a bien défini des normes,
mais les autres librairies tiers (certaines écrites avant que la STL ne
se diffuse) utilisent d'autres normes.

Je ne connais aucun langage qui *oblige* à des usages particuliers pour
définir les identificateurs. C'est du ressort du choix des développeurs
et des normes qu'ils ont l'habitude d'appliquer.
C'est vrai que Java - au moins pour les noms des classes - a essayé de
définir des normes qui sont relativement respectées.
Mais il y a la même chose pour Python:
http://www.python.org/peps/pep-0008.html ... qui laisse quand même une
grande liberté "The naming conventions of Python's library are a bit of
a mess" :-)
Mais quand on regarde, globalement c'est pas trop mal respecté.
Types builtin -> minuscules
Classes -> CapWords

Enfin, le langage n'empêche pas de lire la doc - au moins pour avoir les
noms des modules et classes dont on a besoin. Après, l'intuitivité de
Python se trouve plutôt sur tout ce qui est itérations, notations
d'indexs & Co.

A+


Laurent.

Zennnn http://www.python.org/doc/Humor.html

Avatar
bruno at modulix
Laurent Pointal wrote:
(snip)
Je ne connais aucun langage qui *oblige* à des usages particuliers pour
définir les identificateurs.


Ruby.

Et ce n'est plus idiot que l'indentation significative AMHA.

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"

Avatar
Eric Jacoboni
Laurent Pointal writes:


Je ne connais aucun langage qui *oblige* à des usages particuliers pour
définir les identificateurs. C'est du ressort du choix des développeurs
et des normes qu'ils ont l'habitude d'appliquer.


Si, il y en a... En Haskell, par exemple, tu n'as pas le choix, en
Ruby non plus. En Haskell (dont s'inspire pourtant Python sur certains
points), ce qui commence par une majuscule est un type, le reste est
un identificateur de fonction ou de variable ; en Ruby, tout ce qui
commence par une majuscule est soit une constante, soit un nom de
classe. Le reste doit commencer par une minuscule (pour faire court).

Je ne vois pas pourquoi on *obligerait* à indenter alors qu'on
n'oblige pas à respecter une casse, ce n'est pas cohérent.

C'est vrai que Java - au moins pour les noms des classes - a essayé de
définir des normes qui sont relativement respectées.


Elles le sont en pratique, en tous cas dans l'API fournie, je suis désolé.

Mais il y a la même chose pour Python:
http://www.python.org/peps/pep-0008.html ... qui laisse quand même une
grande liberté "The naming conventions of Python's library are a bit of
a mess" :-)


Voilà, mais un "bit of a mess", j'appelle ça un gros bordel et une
syntaxe non cohérente, moi ;)

Enfin, le langage n'empêche pas de lire la doc - au moins pour avoir les
noms des modules et classes dont on a besoin. Après, l'intuitivité de
Python se trouve plutôt sur tout ce qui est itérations, notations
d'indexs & Co.


Moué... enfin... je suis très très déçu, là :(

Avatar
bruno at modulix
Eric Jacoboni wrote:
Laurent Pointal writes:


Je dirais que c'est historique.



C'est ce je craignais... mais si c'est historique, pourquoi les
évolutions du langage n'ont pas intégré de wrappers pour unifier
l'existant ?



Bonne question. Peut-être pour éviter de casser du code existant ?

Faire évoluer un langage dans tout casser n'est pas une chose aisée - à
moins qu'il n'y ait pas d'utilisateurs du langage, bien sûr. Quand
l'évolution touche à quelque chose d'aussi essentiel que la
représentation interne, c'est encore plus délicat.

La situation actuelle (coexistence de deux modèles) est liée au choix,
justement, d'unifier les types builtins et les types utilisateurs, tout
en préservant la compatibilité. C'est une situation bancale, et il est
clair que la simplicité du langage en prend (momentanément) un coup. Ca
reste un progrès par rapport à la situation précédente.

Les types de base (qui sont des classes!) sont en minuscules.
Les type définis dans des modules tiers utilisent en général des
majuscules au début des mots (mais comme toute règle générale, on doit
sûrement pouvoir y trouver de exceptions).

Certains types étaient précédement dispos dans des modules séparés (ex.
Set, FrozenSet) et sont passés en minuscules lorsqu'ils ont été passé en
builtins (set, frozenset en 2.4).



Oui, mais si c'est ça, la sacro-sainte « intuitivité » du langage un
prend un sacré coup sur le museau parce que s'il faut se rappeler des
orthographes particulières de chaque classe, c'est quand même un peu
moyen pour un langage moderne. J'ai même beaucoup de mal à croire
qu'il en soit ainsi, d'ailleurs : C, C++, Java etc. n'ayant pas ce
défaut, je comprendrais mal que Python l'ait.


Pardon ?

En C comme en C++ comme en Java, les identifiants des types 'builtin'
(int, char, float etc) sont des mots-clés du langage, et il n'y a aucune
règle *officielle* (ie: déterminée par la norme ou la grammaire)
concernant le nommage des types utilisateurs. Les identifiants de type
des bibliothèques standards Java respectent effectivement une
convention, on ne peut pas en dire autant en C++.

Ce qu'il faut comprendre est qu'avant l'unification des types, Python
faisait - comme C++ et Java - une distinction entre types builtins et
types utilisateurs - avec par contre des types builtin bien plus évolués
que ceux de C/C++/Java. Le fait de réduire autant que possible cette
distinction est clairement un progrès par rapport à la situation
antérieure. En l'occurrence, s'il y a défaut, ce serait plutôt du côté
des autres langages "modernes" que tu cite AMHA !-)

NB : sur le fond, je suis d'accord que c'est ch... et moche et pas
intuitif, et j'espère que p3k corrigera ça (BTW, il serait peut-être bon
d'évoquer le sujet sur le wiki concerné).

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
bruno at modulix
Eric Jacoboni wrote:
Laurent Pointal writes:



Je ne connais aucun langage qui *oblige* à des usages particuliers pour
définir les identificateurs. C'est du ressort du choix des développeurs
et des normes qu'ils ont l'habitude d'appliquer.



Si, il y en a... En Haskell, par exemple, tu n'as pas le choix, en
Ruby non plus. En Haskell (dont s'inspire pourtant Python sur certains
points), ce qui commence par une majuscule est un type, le reste est
un identificateur de fonction ou de variable ; en Ruby, tout ce qui
commence par une majuscule est soit une constante, soit un nom de
classe. Le reste doit commencer par une minuscule (pour faire court).

Je ne vois pas pourquoi on *obligerait* à indenter alors qu'on
n'oblige pas à respecter une casse, ce n'est pas cohérent.


Tu va un peu vite, là. je suis d'accord sur le fait qu'il n'est pas
forcément plus idiot d'intégrer cette règle dans la grammaire que celle
concernant l'indentation, mais je ne vois absolument pas en quoi faire
l'autre sans l'un (ou l'un sans l'autre) serait "incohérent".


C'est vrai que Java - au moins pour les noms des classes - a essayé de
définir des normes qui sont relativement respectées.



Elles le sont en pratique, en tous cas dans l'API fournie, je suis désolé.


Les noms des *classes*, oui. Ceux des types "builtin" (int, float etc)
ne suivent pas cette convention. En python (>= 2.2), la principale
différence entre types builtins et types utilisateurs est la casse. En
Java, cette différence est bien plus importante, et ça n'a pas l'air de
te gêner !-)

(snip)

Enfin, le langage n'empêche pas de lire la doc - au moins pour avoir les
noms des modules et classes dont on a besoin. Après, l'intuitivité de
Python se trouve plutôt sur tout ce qui est itérations, notations
d'indexs & Co.



Moué... enfin... je suis très très déçu, là :(


Par contre, tu trouves normal que Java - qui est partout présenté comme
*le* langage 'objet' de référence - ait des types builtins qui se
comportent très différemment des types utilisateurs ?

Personnellement, je trouve plus de cohérence dans le bazar Python que
dans la cathédrale Java. Ca ne veut pas dire qu'il n'y ait rien à
améliorer, mais franchement, la casses des types builtins, c'est un rien
cosmétique...

--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in ''.split('@')])"


Avatar
Laurent Pointal
Eric Jacoboni wrote:
Laurent Pointal writes:

Je ne connais aucun langage qui *oblige* à des usages particuliers pour
définir les identificateurs. C'est du ressort du choix des développeurs
et des normes qu'ils ont l'habitude d'appliquer.



Si, il y en a... En Haskell, par exemple, tu n'as pas le choix, en
Ruby non plus. En Haskell (dont s'inspire pourtant Python sur certains
points), ce qui commence par une majuscule est un type, le reste est
un identificateur de fonction ou de variable ; en Ruby, tout ce qui
commence par une majuscule est soit une constante, soit un nom de
classe. Le reste doit commencer par une minuscule (pour faire court).


Hop, j'ai appris quelque chose.

Je ne vois pas pourquoi on *obligerait* à indenter alors qu'on
n'oblige pas à respecter une casse, ce n'est pas cohérent.


Mais on t'oblige à respecter une casse: celle telle que tu as défini ta
variable.

C'est vrai que Java - au moins pour les noms des classes - a essayé de
définir des normes qui sont relativement respectées.


Elles le sont en pratique, en tous cas dans l'API fournie, je suis désolé.


Mais il y a la même chose pour Python:
http://www.python.org/peps/pep-0008.html ... qui laisse quand même une
grande liberté "The naming conventions of Python's library are a bit of
a mess" :-)


Voilà, mais un "bit of a mess", j'appelle ça un gros bordel et une
syntaxe non cohérente, moi ;)

Enfin, le langage n'empêche pas de lire la doc - au moins pour avoir les
noms des modules et classes dont on a besoin. Après, l'intuitivité de
Python se trouve plutôt sur tout ce qui est itérations, notations
d'indexs & Co.


Moué... enfin... je suis très très déçu, là :(


Faut pas.

Une normalisation comme ça c'est mieux, c'est sûr.
Mais ce n'est pas la panacée.
Perso, j'ai pesté contre Java car leurs méthodes d'accès aux éléments
types séquences n'étaient pas homogènes - et je pense qu'avoir à se
replonger à chaque fois dans une doc pour savoir s'il faut passer par un
itérateur ou bien récupérer la taille et manipuler un index - c'est
vraiment galère, idem d'avoir X types de données (sûrement tout à fait
justifiés) pour faire presque la même chose.
C'est vrai qu'il y a les IDE qui affichent en ligne les docs... mais
finalement on en arrive à avoir besoin d'usines à gaz d'édition
(Eclipse, NetBeans...) pour compenser la conception des outils de base
dispos dans le langage.
Bon, il semble que Java 1.5 ait fait des progrès sur l'homogénéité.


Avatar
Eric Jacoboni
bruno at modulix writes:

[désolé pour le lag, mais je suis en panne d'adéesseelle chez moi :( ]

C'est ce je craignais... mais si c'est historique, pourquoi les
évolutions du langage n'ont pas intégré de wrappers pour unifier
l'existant ?



Bonne question. Peut-être pour éviter de casser du code existant ?
Faire évoluer un langage dans tout casser n'est pas une chose aisée - à
moins qu'il n'y ait pas d'utilisateurs du langage, bien sûr. Quand
l'évolution touche à quelque chose d'aussi essentiel que la
représentation interne, c'est encore plus délicat.



C'était bien dans cette optique que je parlais de wrapper... faire de
Date un alias de date, de DateTime un alias de datetime...

NB : sur le fond, je suis d'accord que c'est ch... et moche et pas
intuitif, et j'espère que p3k corrigera ça (BTW, il serait peut-être bon
d'évoquer le sujet sur le wiki concerné).


Certes. Mon intention n'était pas de lancer un débat là-dessus non
plus. Je me posais juste cette question et je voulais simplement être
sûr que je n'avais pas loupé quelque chose...


Avatar
Eric Jacoboni
bruno at modulix writes:

Je ne vois pas pourquoi on *obligerait* à indenter alors qu'on
n'oblige pas à respecter une casse, ce n'est pas cohérent.


Tu va un peu vite, là. je suis d'accord sur le fait qu'il n'est pas
forcément plus idiot d'intégrer cette règle dans la grammaire que celle
concernant l'indentation, mais je ne vois absolument pas en quoi faire
l'autre sans l'un (ou l'un sans l'autre) serait "incohérent".


Parce que, selon moi, si l'on impose une certaine syntaxe dans le
layout d'un programme, la cohérence voudrait que l'on impose également
une certaine discipline dans la syntaxe. C'est ce que fait Haskell,
par exemple. Pour moi « incohérent », ça signifie exactement ça, pas
plus..

Les noms des *classes*, oui. Ceux des types "builtin" (int, float etc)
ne suivent pas cette convention. En python (>= 2.2), la principale
différence entre types builtins et types utilisateurs est la casse. En
Java, cette différence est bien plus importante, et ça n'a pas l'air de
te gêner !-)


En Java ça ne me gêne pas pour une bonne raison : les types primitifs
sont peu nombreux et parfaitement répertoriés. Tout le reste est
classe. Donc, oui, /du point de vue de la syntaxe/ c'est parfaitement
clair : il suffit de connaitre les types primitifs. Après, si j'ai
besoin d'une classe "time delta" en java, je sais qu'elle s'appelera
TimeDelta. C'est peut-être futile, mais pour moi, ça relève du même
principe qu'aimer voir un texte correctement formaté, avec des
paragraphes bien délimités, des majuscules sur les noms propres et
tout le toutim.

Par contre, tu trouves normal que Java - qui est partout présenté
comme *le* langage 'objet' de référence - ait des types builtins qui
se comportent très différemment des types utilisateurs ?


Entendons nous bien, je ne veux pas parler ici des avantages comparés
de l'approche POO de Java ou Python : je ne parlais que de cette
histoire de conventions de noms.

La casses des types builtins, c'est un rien cosmétique...


Pour toi, pas pour moi. Un langage, pour moi, c'est un tout et ce
n'est pas uniquement un problème de "cosmétique" de voir parfois écrit
"untype" parfois "AutreType" dans le même source. Comme je suis
réaliste et que je sais que la perfection n'est pas de ce monde, je
fais avec... et je note des choses qui ne plaisent pas dans les
différents langages qu'il m'est donné de pratiquer, mais ça ne
m'empêche pas de continuer à les pratiquer pour ce qu'ils
valent. Donc, je peux dire pourquoi j'apprécie Python, mais je peux
aussi dire ce qui me gonfle avec lui.

Comme je l'ai dit, j'ai posé la question initiale de ce thread pour
être sûr que je passais pas à côté de quelque chose qui me semble
"gros", à moi. Maintenant que j'ai la réponse, ce n'est pas pour ça
que je vais jeter Python aux orties... il y avait déjà d'autres choses
qui me gênaient et ça ne m'a pas empêché de continuer de m'intéresser au
langage (mais c'est un peu le cas de /presque/ tous les langages).


1 2