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

Python Discussion :

Organiser ses classes


Sujet :

Python

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 114
    Points : 129
    Points
    129
    Par défaut Organiser ses classes
    Bonjour

    Voici mon problème :

    Avec le temps, mes classes sont de plus en plus grosses, on trouve toujours de nouvelles méthodes à ajouter.
    J'essaye toujours d'avoir des fichiers plutôt petits. L'une des principales raisons est qu'avec SVN, cela permet de mieux voir si une modification est locale (on a juste retoucher une méthode) ou globale (on a complètement revu toutes les méthodes). En C, j'en arrivais parfois à un fichier par fonction.


    Actuellement, j'ai un fichier par classe. Découper jusqu'à ce niveau est facile. Malgré cela, dans certain cas, je commence à trouver ces fichiers trop gros, donc je cherche comment séparer le contenu de cette classe sur plusieurs fichiers.

    Mon premier essai, qui a échoué, consistait en gros à faire ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    fichier class_a_core.py
    class A:
        def __init__(self):
            print("A.__init__")
     
        def m1(self):
            print("A.methode 1")
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fichier class_a_tools.py
    class A:
        def m2(self):
            print("A.methode 2")
    et un exemple d'utilisation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    from multi_fic.class_a_tools import *
    from multi_fic.class_a_core import *
     
    a = A()
     
    a.m2()
    Bien sur cela ne marche pas.


    Est-ce que quelqu'un a une piste pour que j'arrive à découper mon application en petit fichier.

    Cordialement
    Emmanuel

  2. #2
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut, je ne saisis pas trop bien, quand tu importe avec "import*", tu importe deux classes du même nom, à savoir "A".

    A la ligne a = A() comment Python s'y retrouve-t-il ?

    J'utilise assez bien la séparation en fichier, ça n'a rien de compliqué.

    Ex:

    J' ai un fichier Otool.py, qui contient une série d'utilitaires classiques, conversion, algorythmes récurrents etc
    Celui-ci commence comme ceci:

    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
     
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
     
    import os
    import etc
     
    class Tools():
        """Some tools wich are used by the application.
     
        """ 
        def __init__(self):
             ...do something
     
     
        def valid_image(self, fp):
             1ere méthode
     
        def etc...
    Ensuite dans le corps du programme principal;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    from Otool import Tools
     
    tool = Tools()
    ...
    et lorsque j'ai besoin d'une méthode:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
        x = tool.valid_image(image)
    simple, non ?

    vincent

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 114
    Points : 129
    Points
    129
    Par défaut
    Citation Envoyé par VinsS Voir le message
    J' ai un fichier Otool.py, qui contient une série d'utilitaires classiques, conversion, algorythmes récurrents etc
    OK, tu as un fichier Otool.py avec ta classe Tools().
    Maintenant, tu fais grossir ta classe Tools, tu rajoutes des méthodes.
    Si, pour des raisons que j'ai cité précédemment, tu finis par trouver le fichier Otool.py trop long et que tu souhaites diviser ce fichier en plusieurs fichiers, par exemple Otool_1.py et Otool_2.py, tu procèdes comment ? Voilà ma question.

    Cordialement
    Emmanuel

  4. #4
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Bonjour,
    Pour moi c'est une erreur que de vouloir fractionner une même classe et d'ailleur je sais pas si c'est possible en python.
    Une classe est sensée regrouper une ensemble de fonction ayant attrait à un objet. Si ta classe est trop grande, regarde plutôt du côté de la conception. Peut être mets-tu trop de chose dans une même classe (trop procédural), et tu augmentes ainsi ton couplage.
    Si ta classe est longue, mais que toutes les méthodes sont liées à l'objet, pour moi il n'y a pas de problème. D'ailleurs il est parfois bon de regrouper plusieurs classes dans un même fichier afin de regrouper les classes similaires, et permettre des imports plus cohérents
    Bref, je répond pas à ta question d'un point de vue technique...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 114
    Points : 129
    Points
    129
    Par défaut
    Bonjour,

    Citation Envoyé par dahtah Voir le message
    Si ta classe est trop grande, regarde plutôt du côté de la conception. Peut être mets-tu trop de chose dans une même classe
    Citation Envoyé par dahtah Voir le message
    Bref, je répond pas à ta question d'un point de vue technique...
    Si, tu réponds très bien.
    Si je ne me trompes pas, ton point de vu est que :
    - une classe est dans un seul fichier. règle python inviolable.
    - si la classe est trop grande, c'est une erreur de conception. Point de vu que j'accepte.

    merci de ta réponse.

    Est-ce que d'autre personne partage ce point de vu ?

    Cordialement
    Emmanuel

  6. #6
    Membre éclairé
    Profil pro
    Ingénieur sécurité
    Inscrit en
    Février 2007
    Messages
    574
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2007
    Messages : 574
    Points : 751
    Points
    751
    Par défaut
    Citation Envoyé par emmanuel_dumas Voir le message
    - une classe est dans un seul fichier. règle python inviolable.
    Techniquement, je sais pas si tu peux scinder une classe en plusieurs fichiers en python. Je sais que c'est possible en C#. Notament dans les éditeurs d'IHM, où le code généré automatiquement est séparé du code programmeur. Pourtant les deux fichiers forment une même classe (mais bon, c'est un besoin spécifique).
    Citation Envoyé par emmanuel_dumas Voir le message
    - si la classe est trop grande, c'est une erreur de conception. Point de vu que j'accepte.
    Je trouve que sur un gros projet, un des points difficiles de la POO est la granularité des objets. De très gros objets qui font tout sont difficilement maintenables. Maintenant, de très petits objets, obligent à faire beaucoup de code "ciment" entre les objets, et le code est difficile à lire, car les appels aux autres objets obligent le programmeur à aller voir d'autres fichiers, puis d'autres, puis d'autres... Tu obtiens une structure "horizontale" dans un schéma UML.

    Pour être pratique, je dirais que 200-300 lignes par objet sont acceptables. Après, c'est surtout une histoire de fonctionnalités communes. Cet avis bien sur n'engage que moi.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 71
    Points : 56
    Points
    56
    Par défaut
    Bonjour,
    Citation Envoyé par emmanuel_dumas Voir le message
    Si je ne me trompes pas, ton point de vu est que :
    - une classe est dans un seul fichier. règle python inviolable.
    - si la classe est trop grande, c'est une erreur de conception. Point de vu que j'accepte.

    merci de ta réponse.

    Est-ce que d'autre personne partage ce point de vu ?
    Oui, scinder une classe en plusieurs fichiers ma paraît être une erreur, a priori. Ça peut vite devenir le bordel. De plus, est-ce possible en Python? Ça m’étonnerait.

    Par contre, une classe trop grande, je ne sais pas trop ce que ça veut dire. Combien de lignes font tes classes trop grandes?

    Quelques centaines de lignes, c’est correct. Mes classes ne dépassent guère 500 lignes et font souvent beaucoup moins.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    114
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 114
    Points : 129
    Points
    129
    Par défaut
    Citation Envoyé par MorganStern Voir le message
    Par contre, une classe trop grande, je ne sais pas trop ce que ça veut dire. Combien de lignes font tes classes trop grandes
    La classe qui m'a poussé à poster ce message fait actuellement 700 lignes. je vois rapidement un triplement de la taille de cette classe.

    Cordialement
    Emmanuel

  9. #9
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 462
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 462
    Points : 9 249
    Points
    9 249
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je crois aussi qu'on ne peut pas scinder une classe sur plusieurs pages, parce que l'importation d'un module nécessite son exécution.

    Par contre, on peut faire en sorte de placer dans un autre module à importer, le code de certaines méthodes longues sous forme de fonction.

    Cependant, cela pose peut-être plus le problème de l'outil de développement que la longueur effective de la page. Avec eclipse+pydev, par exemple, une grande classe peut être affichée avec uniquement les titres des méthodes. Il suffit alors de cliquer sur le '+' dans la marge pour que le code de la méthode apparaisse. Et un nouveau clic sur le '-' dans la marge pour que soit retiré l'affichage de tout le code de la méthode. Cela permet d'avoir une vue d'ensemble de la classe, même si elle est très grande.

    Tyrtamos
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Points : 224
    Points
    224
    Par défaut
    Si tu tiens vraiment à découper ta classe en plusieurs fichiers, pourquoi ne pas utiliser l'héritage ?
    Une classe mère qui implémente une partie des méthodes, une classe fille qui hérite de la classe mère (et donc de ses méthodes) et qui implémentet celles qui restent.
    Attention ensuite à bien implémenter des objets du type de la classe fille pour avoir accès à toutes les méthodes (mais un problème du genre se serait posé aussi en découpant la classe comme tu as tenté de le faire au début : en n'important que le module "core" il t'aurait manqué des méthodes).
    Je dis une bêtise ?

    edit, petite illustration dans l'interpréteur :
    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
    Python 2.6.4 (r264:75706, Oct 27 2009, 06:16:59) 
    [GCC 4.4.1] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> class A_mere:
    ...        def affiche(self):
    ...             print "ceci est une méthode de héritée de A_mere"
    ... 
    >>> class A(A_mere):
    ...        def encore(self):
    ...             print "ceci est une méthode implémentée par la fille"
    ... 
    >>> x = A()
    >>> x.affiche()
    ceci est une méthode de héritée de A_mere
    >>> x.encore()
    ceci est une méthode implémentée par la fille
    >>>
    Rien ne t'empêche de mettre ces deux classes dans deux fichiers différents.

  11. #11
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Abordons le problème différemment.
    Une classe définit une entité et les méthodes associées sont à priori limitées au opérations associés.

    Si vous avez des classes trop grosses, çà signifie - peut être - qu'elles empilent ou mélangent trop d'entités. Dans ce cas vous avez peut être un problème de conception et les possibilités de découper votre classe en plusieurs fichiers n'est peut être de toutes façons pas une solution.

    Note: Si vous voulez faire çà, rien ne vous empêche de lire les fichiers dans un StringIO et de faire un exec pour l'importer.

    Comment faire?
    Personnellement, j'expérimente une méthode qui permet de masquer les détails en sous-classes ou en objets accessibles comme sous classes.

    Exemple: Une entité Tutu peut avoir des méthodes globales, et des entités liées comme par exemple Tutu.Historique Tutu.Planning ayant des methodes spécifiques mais liées à la nature de Tutu.
    Dans ce cas Historique peut être une sous-classe ou une classe de même niveau dans un autre fichier. Le lien entre Historique et Tutu est de la forme 'parent". A l'initialisation (__init__) de Tutu, j'ai une instruction du type:
    self.historique = Historique (parent=self)
    Dans __init__ d'Historique, je mémorise parent:
    self._parent = kwds.get('parent')
    et on peut à partir de là accéder à certains attributs/méthodes du père.

    Cela me permet de tester Historique indépendamment de Tutu, rendre ou pas Historique "public",... Et donc éventuellement de placer Tutu et Historique dans des fichiers différents.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  12. #12
    Expert éminent sénior
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Points : 10 067
    Points
    10 067
    Par défaut
    Il doit être possible de scinder une classe dans plusieurs fichiers en utilisant ensuite la fonction setattr pour ajouter les fonctions à ta classe.

    exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    ## fichier file1.py
    class toto(object):
        def __init__(self, a):
            self.a = a
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ## fichier file2.py
    import file1
     
    def affiche(self, nombre): print self.a, nombre
     
    setattr(file1.toto, "affiche", affiche)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ## fichier file3.py
    import file2
    import file1
     
    test = file1.toto(5)
    test.affiche(10)  ## 5, 10

  13. #13
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Comme cité plus haut, le choix d'un éditeur permettrait de produire fichiers "normaux" snas nécessiter plusieurs pirouettes fastidieuse ou entachant la lisibilité... J'ai en tête l'éditeur leo. Très bon, mais nécéssitant une petit investissement en temps. il fonctionne sur un principe d'outliner, cet outliner permet de "diviser" une clasee ou ce que l'on veux en plusieurs nodes, tout en produisant des fichiers de sortie "normaux", cad sans que cette "division" soit visible, ça ne l'est qu'au sein de l'éditeur... après c'est une question de goûts.

Discussions similaires

  1. [POO] Organiser ses classes (en sous classes)
    Par alexfrere dans le forum Langage
    Réponses: 5
    Dernier message: 20/03/2007, 13h07
  2. [IMPORTANT!] Comment organiser ses recherches
    Par Emmanuel Lecoester dans le forum Firebird
    Réponses: 0
    Dernier message: 29/07/2005, 13h47
  3. [GUI]Organisation des classes
    Par c-top dans le forum Interfaces Graphiques en Java
    Réponses: 9
    Dernier message: 04/03/2005, 17h46
  4. Organisation des classes
    Par R3iTt0R dans le forum Langage
    Réponses: 2
    Dernier message: 02/06/2004, 17h27
  5. [Debutant(e)][eclipse] Comment organiser ses projets ?
    Par Javanaute dans le forum Eclipse Java
    Réponses: 9
    Dernier message: 09/04/2004, 10h07

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