Précédent   Forum des professionnels en informatique > Général Développement > Conception > Outils > BOUML
BOUML Forum d'entraide sur l'outil UML 2 BOUML : modélisation, générateurs, ...
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 13/01/2008, 19h57   #1
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Par défaut Bouml & Python : proposition

Bonsoir,

vous trouverez ici ma proposition de prise en compte de Python dans Bouml. [EDIT] obsolète, la version 2 de la proposition est ici[/EDIT]

de la commenter (le fond, la forme importe peu).

Attention de ne pas prendre pour argent comptant ce que je dis sur Python, gardez à l'esprit que mes connaissances sur Python sont aussi limitées que nouvelles

Bruno
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 13/01/2008, 22h14   #2
Membre Expert
 
Avatar de anthyme
 
Anthyme Caillard
Inscription : mars 2004
Messages : 1 538
Détails du profil
Informations personnelles :
Nom : Anthyme Caillard
Âge : 28
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : mars 2004
Messages : 1 538
Points : 1 244
Points : 1 244
pour ce qui est des accesseurs (inexistant en python) je ne pense pas que '_' represente bien protected.
Je ne pense pas qu'il soit logique d'acceder aux attributs de la super classe qui commence par '_' je pense pas que cela se fasse dans l'implementation de python.
Cela correspond plutôt à 'private'

vis a vis des docstring, je ne les ai jamais vu decallé apres les """


Code :
1
2
3
"""une ligne

---et une autre"""
je les ai toujours vu comme ceci :

Code :
1
2
3
"""une ligne

et une autre"""
Voila bonne continuation
anthyme est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2008, 16h19   #3
Nouveau Membre du Club
 
Inscription : décembre 2007
Messages : 21
Détails du profil
Informations personnelles :
Âge : 49
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : décembre 2007
Messages : 21
Points : 26
Points : 26
Par défaut propal python

Beh ... faut pas chomer par ici ...
donc:
au 2.3
l'operation Class.foo() pour tout Class.__foo (private) dans le reverse ne me
parait pas justifiée.
En python 2.5 pour rendre accessible un __foo on passe par des
properties donnant a l'exec un Class.foo read et/ou write selon le codage
de la property. Pour dire qui si foo() il y a dans le code il se peut, mais ce
n'est pas obligatoire, qu'il soit lié au __foo. La detection du mot clé
property est le seul moyen de prouver un lien explicite. Une autre
routine pourrait retourner __foo sans etre une property. La génération
automatique de foo() peut créer des doublons.
Regarder la doc de __metaclass__ qui permet de traiter une classe comme
un objet au niveau class (génération de classes ou de pré-traitement a
la création de classe. Si il ya un lien avec UML en tenir compte.

2.4
self n'est pas obligatoire mais c'est bien de ne pas permettre de le changer
ça permet de forcer dans les bonnes pratiques des pythonistas

2.5
Qd on a class A(B):
dans le init de A il faudrait rajouter un appel __init__ de la class B
qui n'est pas automatique. Voir le mot-clef super aussi.

dans un module de class (es) il est possible d'avoir des def blabla
non encapsulées dans la class, tout en étant appelable depuis la
classe. C'est le scope module (fichier .py) de python. Si il y a un lien
avec UML, en tenir compte.

2.8
Les chemins relatifs c'est nouveau, je préfererai pas dans un 1er temps
le code est moins clair.

2.10
Un fichier.py peut contenir class A:, class B: etc ... et aussi des def isolées
utilisées dans le module (fichier.py). Si on génère un A.py pour class A
un B.py pour class B, indépendant les uns des autres je vois pas de
probleme. En reverse depuis un existant quid ??

Les chemins de module sont dans python path. Les espaces sont visibles
depuis sys.xxx. Le dict de classe contient ce qui est dans son espace.

Pour le reste c'est joli tout plein
A+
bsadacheng est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2008, 17h02   #4
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Citation:
Envoyé par bsadacheng Voir le message
au 2.3
l'operation Class.foo() pour tout Class.__foo (private) dans le reverse ne me parait pas justifiée.
je suis tout à fait d'accord ... sauf sur le fait que j'ai dit cela
j'ai dis qu'une opération reversée appelée __foo dans le source donnerai une opération appelée foo dans le modèle

ce que je propose c'est que le générateur prenne en compte les visibilités pour ajouter un prefixe automatiquement, l'autre avantage etant de cacher les __ 'pas très beau' quand on a un oeil non pythonesque. Bien évidemment le reverse doit alors retirer le prefixe pour retomber sur ses pieds

mais de toute facon la chose est débraillable, je souhaite juste que vous m'indiquiez les 'bonnes' valeurs par défaut de ces settings selon vous

Citation:
2.5
Qd on a class A(B):
dans le init de A il faudrait rajouter un appel __init__ de la class B
qui n'est pas automatique. Voir le mot-clef super aussi.
ca c'est c'est à l'utilisateur de le faire, comment pourrais-je savoir ce qu'il faut donner en argument s'il y en a ?

Citation:
dans un module de class (es) il est possible d'avoir des def blabla
non encapsulées dans la class, tout en étant appelable depuis la
classe. C'est le scope module (fichier .py) de python. Si il y a un lien
avec UML, en tenir compte.
ce genre de chose n'est pas modélisable en UML, mais :
  • cela n'est pas perdu par le reverse (partie 1 ou 3 cf 2.10)
  • c'est possible à générer en le mettant directement dans la définition de l'artifact, ou en l'attachant à la définition d'une classe en le mettant avant ou après. La seule chose c'est que c'est du texte pur et dur

Citation:
2.10
Un fichier.py peut contenir class A:, class B: etc ... et aussi des def isolées
utilisées dans le module (fichier.py). Si on génère un A.py pour class A
un B.py pour class B, indépendant les uns des autres je vois pas de
probleme. En reverse depuis un existant quid ??
on c'est mal compris, je n'ai peut etre pas été assez clair dans la doc

si les classes A et B sont associée à l'artifact C, alors les classes A et B seront produites dans C.py, le problème n'est pas là

dans Bouml si on veut produire le code de la classe A dans le fichier F.py il faut :
  1. creer la classe avec ses membres
  2. creer si besoin une vue de deployment
  3. creer un artifact dans la vue de deployment et l'appeler F
  4. editer l'artifact pour mettre sont stéréotype à "source" et pour demander l'association avec A

c'est donc assez lourd, pour aider on peut demander à Bouml de faire lui-même les étapes 2 à 4 via le menu de la classe, et le plug-out appelé deploy classse le fait pour toutes les classes d'une vue de classes qui n'ont pas d'artifact associé. Le problème est que dans ce cas là les artifacts crées portent le nom de leur classe associée (évidemment il est ensuite possible de les renommer, mais s'il y a 100 artifacts ...)
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2008, 21h07   #5
Nouveau Membre du Club
 
Inscription : décembre 2007
Messages : 21
Détails du profil
Informations personnelles :
Âge : 49
Localisation : France, Isère (Rhône Alpes)

Informations forums :
Inscription : décembre 2007
Messages : 21
Points : 26
Points : 26
Citation:
Envoyé par bsadacheng Voir le message
au 2.3
l'operation Class.foo() pour tout Class.__foo (private) dans le reverse ne me parait pas justifiée.
je suis tout à fait d'accord ... sauf sur le fait que j'ai dit cela
j'ai dis qu'une opération reversée appelée __foo dans le source donnerai une opération appelée foo dans le modèle

ce que je propose c'est que le générateur prenne en compte les visibilités pour ajouter un prefixe automatiquement, l'autre avantage etant de cacher les __ 'pas très beau' quand on a un oeil non pythonesque. Bien évidemment le reverse doit alors retirer le prefixe pour retomber sur ses pieds

mais de toute facon la chose est débraillable, je souhaite juste que vous m'indiquiez les 'bonnes' valeurs par défaut de ces settings selon vous
____________
le protected avec _ est une bonne idée, ya pas mal de code comme ça
ou le _ veut bien dire "la c'est moi qui jardine" pas touche.
Les choix me paraissent les bons. Masquer le __ et le _ dans le modèle
oui bien sur puisque les tag potected,private etc sont gérés par bouml
no problem.

Citation:
2.5
Qd on a class A(B):
dans le init de A il faudrait rajouter un appel __init__ de la class B
qui n'est pas automatique. Voir le mot-clef super aussi.

ca c'est c'est à l'utilisateur de le faire, comment pourrais-je savoir ce qu'il faut donner en argument s'il y en a ?
_________
certes les arguments .... et vu le nombre de façons de les passer ....
Mouais ... Ne pas le faire c'est generer du code non fonctionnel.
Pas beau. Par contre bouml connait les parametres de création de la super classe ( il a le init ) donc l'insertion de cette signature doit etre possible.
Si c'est trop compliqué, mettre la signature avec () liste de parametres vide.
Le code va se vautrer lamentablement mais au moins le progrmmeur saura
où et pourquoi (aveugle ??).
Par contre si le reverse ellimine la signature en la vidant
encore pas beau. Le reverse pourrait commenter le code qd il ne peut pas faire ce qu'il lit comme code? Je délire peut-etre ....


Citation:
dans un module de class (es) il est possible d'avoir des def blabla
non encapsulées dans la class, tout en étant appelable depuis la
classe. C'est le scope module (fichier .py) de python. Si il y a un lien
avec UML, en tenir compte.

ce genre de chose n'est pas modélisable en UML, mais :

* cela n'est pas perdu par le reverse (partie 1 ou 3 cf 2.10)
* c'est possible à générer en le mettant directement dans la définition de l'artifact, ou en l'attachant à la définition d'une classe en le mettant avant ou après. La seule chose c'est que c'est du texte pur et dur

Magnifique !!! On est sauvé !!!


Citation:
2.10
Un fichier.py peut contenir class A:, class B: etc ... et aussi des def isolées
utilisées dans le module (fichier.py). Si on génère un A.py pour class A
un B.py pour class B, indépendant les uns des autres je vois pas de
probleme. En reverse depuis un existant quid ??

on c'est mal compris, je n'ai peut etre pas été assez clair dans la doc

si les classes A et B sont associée à l'artifact C, alors les classes A et B seront produites dans C.py, le problème n'est pas là

dans Bouml si on veut produire le code de la classe A dans le fichier F.py il faut :

1. creer la classe avec ses membres
2. creer si besoin une vue de deployment
3. creer un artifact dans la vue de deployment et l'appeler F
4. editer l'artifact pour mettre sont stéréotype à "source" et pour demander l'association avec A


c'est donc assez lourd, pour aider on peut demander à Bouml de faire lui-même les étapes 2 à 4 via le menu de la classe, et le plug-out appelé deploy classse le fait pour toutes les classes d'une vue de classes qui n'ont pas d'artifact associé. Le problème est que dans ce cas là les artifacts crées portent le nom de leur classe associée (évidemment il est ensuite possible de les renommer, mais s'il y a 100 artifacts ...)

J'ai pas compris ... Je connais pas assez bien bouml.

Par contre dans
2.6.1.3 macros


${type} : produit le type de l'attribut, par exemple pour l'utiliser dans un commentaire, éventuellement en plaçant celui-ci directement dans la définition
*

Là ya un truc intéressant a faire. Si c'est posible evidemment.
Le type en python est connu a l'exec soit; Mais il est possible de wrapper
la modif d'un attribut pour verifier le type. On peut faire ça avec un
decorator donc on pourrait avoir dédoublement de ${type} en
${typed} , l'info du type irait dans la doc, et ${typev}${deco} ou deco
serait le decorator de validation des types donc un nom de fonction
et le géné devrait ecrire @deco devant la routine de modif de l'attribut.
On est peut-etre trop loin de UML et trop dans python là ???
Le code du decorator juste pour rire, et pour les codeurs qui
lisent
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
    def require(*types):
    """Return a decorator function that requires specified types.
       types -- tuple each element of which is a type or class or a tuple of
                several types or classes.
       Example to require a string then a numeric argument
       @require(str, (int, long, float))
       will do the trick"""
       def deco(func):
        """Decorator function to be returned from require().  Returns a function
           wrapper that validates argument types."""
        def wrapper (*args):
            """Function wrapper that checks argument types."""
            assert len(args) == len(types), 'Wrong number of arguments.'
            for a, t in zip(args, types):
                if type(t) == type(()):
                    # any of these types are ok
                    msg = """%s is not a valid type. Valid types:\n%s"""
                    assert sum(isinstance(a, tp) for tp in t) > 0, \
                                msg % (a, '\n'.join(str(x) for x in t))
                assert isinstance(a, t), '%s is not a %s type' % (a, t)
            return func(*args)
        return wrapper
    return deco
Bon ben voilou ...
A+
bsadacheng est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2008, 22h04   #6
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
par pitié bsadacheng, ne fait pas les citations à la main, tu dois te rendre compte qu'il y a comme une différence entre l'affichage de ton message et les autres

Citation:
Envoyé par bsadacheng Voir le message
Citation:
certes les arguments .... et vu le nombre de façons de les passer ....
Mouais ... Ne pas le faire c'est generer du code non fonctionnel.
on c'est mal compris, si tu demandes à Bouml de produite super.__init__(1, ${v2}) il le fera. Par contre il n'a pas de boule de cristal lui permettant de deviner qu'il faut appeler l'__init__ de la classe super avec 1 en premier argument et le troisième paramètre courant en second paramètre

Citation:
Par contre bouml connait les parametres de création de la super classe ( il a le init ) donc l'insertion de cette signature doit etre possible.
Si c'est trop compliqué, mettre la signature avec () liste de parametres vide.
Le code va se vautrer lamentablement mais au moins le progrmmeur saura
où et pourquoi (aveugle ??).
non, ca c'est de l'algorithmie, c'est à l'utilisateur de faire ce genre de chose, encore une fois Bouml n'est pas extra lucide

Citation:
Par contre si le reverse ellimine la signature en la vidant
encore pas beau.
mais d'où sortez-vous tout ces trucs ?

Bouml ne vide aucune signature au reverse, ni les corps des opérations etc ...
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/01/2008, 23h22   #7
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Citation:
Envoyé par bsadacheng Voir le message
Là ya un truc intéressant a faire. Si c'est posible evidemment.
Le type en python est connu a l'exec soit; Mais il est possible de wrapper
la modif d'un attribut pour verifier le type. On peut faire ça avec un
decorator donc on pourrait avoir dédoublement de ${type} en
${typed} , l'info du type irait dans la doc, et ${typev}${deco} ou deco
serait le decorator de validation des types donc un nom de fonction
et le géné devrait ecrire @deco devant la routine de modif de l'attribut.
On est peut-etre trop loin de UML et trop dans python là ???
désolé, j'avais raté la fin

inutile de dédoubler ${type} en deux nouvelles macros, tu peux écrire ${type} autant de fois que tu veux, cela ne s'use pas

si tu veux que Bouml produise '@deco' alors mets '@deco' directement là où tu veux, il est inutile de me demander de faire une macro pour cela

petit rappel : les plug-outs sont là pour automatiser ce que vous ne souhaitez pas faire à la main, donc n'hésitez pas à faire des plug-outs modifiant vos modèles comme vous le souhaitez
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2008, 10h37   #8
Expert Confirmé Sénior
 
Avatar de Thierry Chappuis
 
Homme Thierry Chappuis
Enseignant Chercheur
Inscription : mai 2005
Messages : 3 481
Détails du profil
Informations personnelles :
Nom : Homme Thierry Chappuis
Âge : 35
Localisation : Suisse

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : mai 2005
Messages : 3 481
Points : 5 051
Points : 5 051
Citation:
Envoyé par Python dans Bouml
Le choix entre les deux peut se faire au niveau de chaque classe via un indicateur dont la valeur pas défaut est indiquée via les generation settings. Pour suivre la règle établie par Python, par défaut cet l'indicateur demande de créer des classes suivant l'ancienne sémantique.

Pour simplifier la vie des utilisateurs, une nouvelle classe qui n'hérite de rien explicitement hérite en fait d'object.
Là je ne suis pas certain de comprendre. Vous dites que, par défaut, l'indicateur demande de créer des classes selon l'ancienne sémantique. Par ailleurs, vous dites également qu'une nouvelle classe qui n'hérite de rien explicitement hérite en fait d'object. N'y a-t'il pas une contradiction? Si le choix par défaut est de créer une classe selon l'ancienne sémantique, pourquoi une classe par défaut devrait-elle hériter d'object.

En ce qui concerne la génération des docstrings, le format que je rencontre le plus (et que j'utilise) est:

Code python :
1
2
3
4
5
class MaClasse(object):
    """une ligne
 
    et les autres."""
    pass

J'ai rarement rencontré:
Code python :
1
2
3
4
5
class MaClasse(object):
    """une ligne
 
       et les autres."""
    pass
Le choix du format est-t'il paramétrable?
Citation:
Envoyé par Python dans Bouml
Question : est-il (vraiment) nécessaire d'avoir un generation settings pour optionnellement produire des chemins relatifs lorsque cela est possible ?
Personnellement, je n'utilse pas les chemin relatifs, mais la possibilité de modifier cela dans les generation settings est certainement une bonne chose.

Citation:
Envoyé par Python dans Bouml
Question: Lorsque l'on demande la création automatique d'un artifact pour une classe n'en ayant pas, l'artifact prend le nom de la classe. Le fichier produit par un artifact lors de la génération de code ayant son nom (plus l'extension) cela implique que les modules sont générallement cachés dans le dictionnaire global par la classe qu'ils contiennent. Cela pose-t-il un problème ?
Là, je ne comprends pas bien ce que tu veux dire. Peux-tu expliciter un peu?


Comment cela se passe-t'il pour les méthodes de classe (décorateur @classmethod) et pour les méthodes statiques (décorateur @staticmethod) à la génération et au reverse? Sinon, je suis enthousiaste.

Meilleures salutations

Thierry
__________________
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

FAQ-Python FAQ-C FAQ-C++

+
Thierry Chappuis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/01/2008, 11h39   #9
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Citation:
Envoyé par Thierry Chappuis Voir le message
Là je ne suis pas certain de comprendre. Vous dites que, par défaut, l'indicateur demande de créer des classes selon l'ancienne sémantique. Par ailleurs, vous dites également qu'une nouvelle classe qui n'hérite de rien explicitement hérite en fait d'object. N'y a-t'il pas une contradiction? Si le choix par défaut est de créer une classe selon l'ancienne sémantique, pourquoi une classe par défaut devrait-elle hériter d'object.
Par défaut Bouml crée des classes suivant l'anciennes sémantique (Python < 2.2). Le fait que object est si besoin hérité pour les nouvelles classes n'est pas contradictoire.
Une classe est ancienne (< Python 2.2) ou-exclusivement nouvelle (Python >= 2.2)

Citation:
J'ai rarement rencontré:
Code python :
1
2
3
4
5
class MaClasse(object):
    """une ligne
 
       et les autres."""
    pass
n'ayant jamais écrit de Python j'ai regardé des exemples issus de DVP, et ceux que j'ai vu utilisaient justement cette notation

Citation:
Le choix du format est-t'il paramétrable?
si tout le monde est finalement contre inutile de le proposer même en option

Citation:
Personnellement, je n'utilse pas les chemin relatifs, mais la possibilité de modifier cela dans les generation settings est certainement une bonne chose.
pareil, pas utile ... pas présent

Citation:
Citation:
Question: Lorsque l'on demande la création automatique d'un artifact pour une classe n'en ayant pas, ...
Là, je ne comprends pas bien ce que tu veux dire. Peux-tu expliciter un peu?
là franchement je ne sais plus quoi dire, si ce n'est : faites un essai sous Bouml avec Java ou Php par exemple, et vous comprendrez tout de suite

Citation:
Comment cela se passe-t'il pour les méthodes de classe (décorateur @classmethod) et pour les méthodes statiques (décorateur @staticmethod) à la génération et au reverse?Thierry
Le reverse conserve les décorateurs, ceux-ci étant éditables/visibles via une boite de dialogue comme les annotations en Java.

Si des décorateurs sont associés à une opération, ceux-ci seront produits par le générateur.

Mais dans ma proposition les décorateurs sont tous soit issus du reverse, soit ajoutés à la main en éditant l'opération. Je ne comptais pas automatiquement ajouter le décorateurs @classmethod lorsqu'une opération est déclarée 'de classe', et par cohérence je ne comptais pas mettre un bouton pour indiquer d'une opération est statique et ajoutant donc @staticmethod. Dans ma proposition il faut donc éditer les décorateurs de l'opération pour ajouter @classmethod ou @staticmethod.

Cependant Bouml pourais très bien ajouter/retirer automatiquement ces décorateurs parmis la liste des décorateurs (sauf ancienne classe). Si tel est le cas il faudrait sans doute ajouter ces décorateurs en fin de liste pour qu'ils soient vus par d'éventuel autres décorateurs car si j'ai bien compris
Code :
1
2
3
4
@decoperso
@classmethod
def m(): ...
correspond à decoperso(classmethod(m)) et donc classmethod sera fait avant decoperso qui aura ainsi plus d'info sur la classe
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 16h24   #10
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
finalement, concernant @classmethod et @staticmethod pour les opérations :
  • ajout de ma macro ${static} , qui produit @staticmethod si c'est le cas, c'est à dire si dans l'onglet UML class operation est coché
  • @classmethod est à la charge de l'utilisateur, bref il doit être mis à la main parmi les décorateurs comme dans ma proposition initiale
  • modification de la définition par défaut qui devient :
    Code :
    1
    2
    3
    ${@}${static}def ${visibility}${name}${(}${)}:
    ${docstring}${body}

P.S. Python aurait vraiment pu choisir autre chose que classmethod qui est très trompeur
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 17h16   #11
Rédacteur/Modérateur
 
Avatar de Matthieu Brucher
 
Matthieu Brucher
Développeur HPC
Inscription : juillet 2005
Messages : 9 607
Détails du profil
Informations personnelles :
Nom : Matthieu Brucher
Âge : 30
Localisation : France, Pyrénées Atlantiques (Aquitaine)

Informations professionnelles :
Activité : Développeur HPC
Secteur : Industrie

Informations forums :
Inscription : juillet 2005
Messages : 9 607
Points : 15 381
Points : 15 381
Dans l'ensemble, j'aime beaucoup ta proposition.
En ce qui concerne les commentaires, j'ai surtout vu ça :
Code :
1
2
3
"""
Un commentaire
"""
Mais c'est accessoire.

C'est quoi le problème avec classmethod ?

Je pense que les nouvelles classes devraient être sélectionnées par défaut, Python 2.2 est suffisamment vieux pour cela, non ?
Matthieu Brucher est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 18h03   #12
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Citation:
Envoyé par Miles Voir le message
En ce qui concerne les commentaires, j'ai surtout vu ça :
Code :
1
2
3
"""
Un commentaire
"""
Je m'oriente vers
Code :
1
2
"""Un commentaire
sur deux lignes"""
Mais pour avoir
Code :
1
2
3
4
"""
Un commentaire
sur deux lignes
"""
il suffit que la description commence et finisse par un saut de ligne

Citation:
Je pense que les nouvelles classes devraient être sélectionnées par défaut, Python 2.2 est suffisamment vieux pour cela, non ?
certes il est assez vieux, mais pas assez aux yeux des auteurs de Python, car
  1. le manuel de référence dit : for compatibility reasons, classes are still old-style by default.
  2. le manuel de référence ne décrit même pas ces nouvelles classes, il faut aller voir un document annexe

Vu ma 'très forte expérience en Python' je ne me sens pas le droit de ne pas suivre les choix du manuel de référence
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 18h14   #13
Rédacteur/Modérateur
 
Avatar de Matthieu Brucher
 
Matthieu Brucher
Développeur HPC
Inscription : juillet 2005
Messages : 9 607
Détails du profil
Informations personnelles :
Nom : Matthieu Brucher
Âge : 30
Localisation : France, Pyrénées Atlantiques (Aquitaine)

Informations professionnelles :
Activité : Développeur HPC
Secteur : Industrie

Informations forums :
Inscription : juillet 2005
Messages : 9 607
Points : 15 381
Points : 15 381
Il est recommandé maintenant de faire des nouvelles classes par défaut, c'est le truc à retenir de Python.
Elles seront d'office "nouvelles" dans Python 3k (même sans object), mais toutes les classes Python sont maintenant nouvelles.
Matthieu Brucher est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 18h15   #14
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Quand une opération est d'instance cette dernière est associée au paramètre self que Bouml rajoute de lui même.

Qu'en est-il pour une @classmethod ?
cls est-t-il le nom de paramètre habituel ?
Bouml doit-il ajouté d'office ce paramètre comme il le fait pour self ?

__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 18h30   #15
Expert Confirmé Sénior
 
Avatar de Thierry Chappuis
 
Homme Thierry Chappuis
Enseignant Chercheur
Inscription : mai 2005
Messages : 3 481
Détails du profil
Informations personnelles :
Nom : Homme Thierry Chappuis
Âge : 35
Localisation : Suisse

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : mai 2005
Messages : 3 481
Points : 5 051
Points : 5 051
Citation:
Envoyé par bruno_pages Voir le message
Quand une opération est d'instance cette dernière est associée au paramètre self que Bouml rajoute de lui même.

Qu'en est-il pour une @classmethod ?
cls est-t-il le nom de paramètre habituel ?
Bouml doit-il ajouté d'office ce paramètre comme il le fait pour self ?

Oui, les méthodes de classe prennent par convention cls en 1er paramètre. Sinon, je suis assez d'accord avec Miles que les classes nouveau style devraient être la classe par défaut. Beaucoup de choses dépendent maintenant du fait qu'une classe est nouveau style: les décorateurs, descripteurs, super, les propriétés, etc. Les classes ancien style ne sont pratiquement plus utilisées dans les nouveaux développements.

Thierry
__________________
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

FAQ-Python FAQ-C FAQ-C++

+
Thierry Chappuis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 19h02   #16
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
Python commence à me les briser menu (c'est pas des gros mots, c'est d'Audiard) avec ces changements continuels à propos des classes (v < 2.2, 2.2 <= v < 4.0, v >= 4.0 ...)

je ne comprends pas vos remarques :
  • toutes les classes Python sont maintenant nouvelles, et pourtant class A : pass c'est bien une ancienne classe, non ?
  • Beaucoup de choses dépendent maintenant du fait qu'une classe est nouveau style: les décorateurs..., et pourtant avec une 2.5 sans utiliser une nouvelle classe je peux faire :
    Code :
    1
    2
    3
    4
    5
    6
    >>> class B:
    ...  @classmethod
    ...  def m(cls) : print cls
    ...
    >>> B.m() 
    __main__.B
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 16/01/2008, 19h35   #17
Rédacteur/Modérateur
 
Avatar de Matthieu Brucher
 
Matthieu Brucher
Développeur HPC
Inscription : juillet 2005
Messages : 9 607
Détails du profil
Informations personnelles :
Nom : Matthieu Brucher
Âge : 30
Localisation : France, Pyrénées Atlantiques (Aquitaine)

Informations professionnelles :
Activité : Développeur HPC
Secteur : Industrie

Informations forums :
Inscription : juillet 2005
Messages : 9 607
Points : 15 381
Points : 15 381
1) oui, mais c'est à éviter.

2) c'est plus sioux que ça, la différence. Faut que je me replonge dans mes écrits pour te donner la réponse.
Matthieu Brucher est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 12h03   #18
Expert Confirmé Sénior
 
Avatar de Thierry Chappuis
 
Homme Thierry Chappuis
Enseignant Chercheur
Inscription : mai 2005
Messages : 3 481
Détails du profil
Informations personnelles :
Nom : Homme Thierry Chappuis
Âge : 35
Localisation : Suisse

Informations professionnelles :
Activité : Enseignant Chercheur
Secteur : Industrie Pharmaceutique

Informations forums :
Inscription : mai 2005
Messages : 3 481
Points : 5 051
Points : 5 051
Citation:
Envoyé par bruno_pages Voir le message
je ne comprends pas vos remarques :
  • toutes les classes Python sont maintenant nouvelles, et pourtant class A : pass c'est bien une ancienne classe, non ?
  • Beaucoup de choses dépendent maintenant du fait qu'une classe est nouveau style: les décorateurs..., et pourtant avec une 2.5 sans utiliser une nouvelle classe je peux faire :
    Code :
    1
    2
    3
    4
    5
    6
    >>> class B:
    ...  @classmethod
    ...  def m(cls) : print cls
    ...
    >>> B.m() 
    __main__.B
1) L'introduction des nouvelles classes avec Python 2.2 et le fait que dans Python 3.0 les classes seront nouveau style par défaut fait que les classes ancien style sont déconseillées (ont-elles le status dépréciéet?). La classe A que tu mentionnes est bien une classe ancien style, car elle ne dérive pas de object.

2) Certes tu peux invoquer le décorateur @classmethod depuis une classe ancien style. Mais si tu désires implanter un tel décorateur (appelons-le MethodeDeClasse), tu dois utiliser un descripteur et la classe MethodeDeClasse doit être nouveau style.

Code python :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class MethodeDeClasse(object):
    """Decorateur destine a l'implantation 
    d'une methode de classe."""
 
    def __init__(self, fonction):
        self.fonction = fonction
 
    def __get__(self, obj, cls=None):
        if cls is None:
            cls = type(obj)
 
        def fonction_decoree(*args):
            return self.fonction(cls, *args)
 
        return fonction_decoree

Les classes ancien style sont capables de gérer un descripteur et donc d'utiliser @classmethod ou @MethodeDeClasse. C'est d'ailleurs ce qu'elles font également lors d'un appel de fonction, une fonction n'étant rien d'autre qu'un descripteur implanté à l'aide d'une classe nouveau style (même dans les classes ancien style). Les classes nouveau style sont donc centrales dans le modèle sous-jacent actuel de Python. L'utilisation systématique de classes nouveau style permet d'harmoniser ce modèle de le rendre beaucoup plus cohérent.

Les classes ancien style sont appelées à disparaître (c'est pour Python 3.0). Python 2.5 ne les conserve que pour des raisons de compatibilité ascendante et je vois que des désavantages à les utiliser. Python tourne aujourd'hui autour des classes nouveau style et il est fortement conseillé de dériver toutes ses classes de object.

EDIT: Il n'y a pas de changement continuel de la sémantique des classes dans Python comme tu semble t'en plaindre. Il y a eu un changement de direction charnière avec Python 2.2. Python évolue désormais vers sa version 3.0 et les classes nouveau style sont de plus en plus mises en avant. Je ne vois pas de complication majeure à utiliser les classes nouveau style par défaut dans Bouml et je pense que cela correspondrait beaucoup plus à l'évolution actuel du langage.

Thierry
__________________
"The most important thing in the kitchen is the waste paper basket and it needs to be centrally located.", Donald Knuth
"If the only tool you have is a hammer, every problem looks like a nail.", probably Abraham Maslow

FAQ-Python FAQ-C FAQ-C++

+
Thierry Chappuis est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 19h49   #19
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576


Je viens de regarder le manuel de ref de la 3.0, il est toujours écrit
Citation:
For compatibility reasons, classes are still old-style by default. New-style classes are created by specifying another new-style class (i.e. a type) as a parent class, or the “top-level type” object if no other parent is needed.
...
This manual is not up-to-date with respect to new-style classes. For now, please see http://www.python.org/doc/newstyle/ for more information.
Une obsolescence reportée de version de doc de ref en version de doc de ref depuis des années c'est vraiment pitoyable , pour me mettre au même niveau j'ai juste à ne pas parler de Python dans la doc de ref de Bouml d'ici au moins 2013

Pour le reste je suis assez perplexe, contrairement à vous ce qui m'importe le plus n'est finalement pas la sémantique mais la syntaxe, et s'il y a une notation appelée à disparaitre c'est bien celle de la 2.2 avec l'héritage explicite d'object (même si elle est tolérée en 3.0).

Le problème majeur concerne bien évidemment le reverse et ce qu'il doit faire lorsqu'il lit class C : pass, car cela peut être une classe < 2.2 ou >= 3.0

Le flag old/new que j'avais prévue ne marchera donc plus avec Python 3.0
Trois solutions possibles :
  • je gère un flag "2.2" pour que l'héritage d'object reste implicite et soit produit pas le générateur si besoin. Le reverse fait ce qu'il peux et positionne ce flag s'il lit un héritage d'object.
  • pas de flag lié à la version, l'héritage d'object est explicite et à la charge de l'utilisateur
  • ne pas intégrer Python dans Bouml avant plusieurs années afin que les versions antérieure à la 3.0 soit oubliées ... aller, c'est pour rire ... quoi que ...

Sinon, j'ai voulus 'trop bien faire', avec trop d'automatisations, ce qui est incompatible avec un langage instable et surtout sans compatibilité ascendante
Donc :
  • Pas de gestion de la visibilité à la génération (pas de macro ${visibility}).
  • Le reverse mettra toutes les opérations à public sauf celles dont le nom commence par __ et qui seront déclarées private.
  • Présence explicite de self ou cls parmi les paramètres (ils ne sont pas ajoutés aux autres paramètre par le générateur en fonction des infos sur les opérations)
  • le reverse ne se base pas sur l'absence de self et cls en premier paramètre pour établir qu'une méthode est statique, mais sur la présence de @staticmethod
  • @classmethod, qui ne devrait pas être l'objet d'une utilisation effrénée, fera juste parti des décorateurs proposés pas défaut

Merci aux participants
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 17/01/2008, 23h37   #20
Modérateur
 
Avatar de bruno_pages
 
Homme bruno pagès
Développeur informatique
Inscription : juin 2005
Messages : 2 970
Détails du profil
Informations personnelles :
Nom : Homme bruno pagès
Âge : 52
Localisation : France

Informations professionnelles :
Activité : Développeur informatique
Secteur : High Tech - Produits et services télécom et Internet

Informations forums :
Inscription : juin 2005
Messages : 2 970
Points : 4 576
Points : 4 576
la version 2 de la proposition est ici
__________________
Bruno Pagès, auteur de Bouml, mes tutoriels sur DVP (vieux, non à jour)
bruno_pages est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 12h06.


 
 
 
 
Partenaires

Hébergement Web