IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

BOUML Discussion :

Bouml & Python : proposition


Sujet :

BOUML

  1. #1
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    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

  2. #2
    Membre éprouvé Avatar de anthyme
    Homme Profil pro
    Inscrit en
    Mars 2004
    Messages
    1 559
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2004
    Messages : 1 559
    Points : 1 257
    Points
    1 257
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    """une ligne
    
    ---et une autre"""
    je les ai toujours vu comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    """une ligne
    
    et une autre"""
    Voila bonne continuation

  3. #3
    Nouveau membre du Club
    Profil pro
    Agent de maîtrise
    Inscrit en
    Décembre 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Agent de maîtrise

    Informations forums :
    Inscription : Décembre 2007
    Messages : 23
    Points : 31
    Points
    31
    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+

  4. #4
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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

    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 ?

    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


    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 ...)

  5. #5
    Nouveau membre du Club
    Profil pro
    Agent de maîtrise
    Inscrit en
    Décembre 2007
    Messages
    23
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Agent de maîtrise

    Informations forums :
    Inscription : Décembre 2007
    Messages : 23
    Points : 31
    Points
    31
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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+

  6. #6
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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

    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

    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 ...

  7. #7
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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

  8. #8
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class MaClasse(object):
        """une ligne
     
        et les autres."""
        pass

    J'ai rarement rencontré:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  9. #9
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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)

    J'ai rarement rencontré:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    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

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

    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

    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

    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  10. #10
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
      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

  11. #11
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Dans l'ensemble, j'aime beaucoup ta proposition.
    En ce qui concerne les commentaires, j'ai surtout vu ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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 ?

  12. #12
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    Citation Envoyé par Miles Voir le message
    En ce qui concerne les commentaires, j'ai surtout vu ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    """
    Un commentaire
    """
    Je m'oriente vers
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    """Un commentaire
    sur deux lignes"""
    Mais pour avoir
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    """
    Un commentaire
    sur deux lignes
    """
    il suffit que la description commence et finisse par un saut de ligne

    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

  13. #13
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    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.

  14. #14
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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 ?


  15. #15
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    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

  16. #16
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      >>> class B:
      ...  @classmethod
      ...  def m(cls) : print cls
      ...
      >>> B.m() 
      __main__.B

  17. #17
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

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

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    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.

  18. #18
    Expert confirmé
    Avatar de Thierry Chappuis
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Mai 2005
    Messages
    3 499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Suisse

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 499
    Points : 5 360
    Points
    5 360
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
      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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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

  19. #19
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut


    Je viens de regarder le manuel de ref de la 3.0, il est toujours écrit
    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

  20. #20
    Modérateur
    Avatar de bruno_pages
    Homme Profil pro
    ingénieur informaticien à la retraite
    Inscrit en
    Juin 2005
    Messages
    3 536
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : ingénieur informaticien à la retraite
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juin 2005
    Messages : 3 536
    Points : 6 727
    Points
    6 727
    Par défaut
    la version 2 de la proposition est ici

Discussions similaires

  1. [bouml]Code python généré d'une metaclasse
    Par cedrix57 dans le forum BOUML
    Réponses: 3
    Dernier message: 18/03/2009, 09h39
  2. Python disponible sous Bouml
    Par bruno_pages dans le forum BOUML
    Réponses: 3
    Dernier message: 28/01/2008, 11h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo