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 :

Import, comment organiser sa solution [Python 3.X]


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Points : 69
    Points
    69
    Par défaut Import, comment organiser sa solution
    Bonjour, j'ai travaille depuis plusieurs années avec C#/.NET et là je suis sur un gros projet qui va se développer en python (3.5).
    Je n'arrive pas à utiliser et organiser ma solution. (notament définir des classe de base ou abstraites dans des fichiers qui seront importés depuis d'autres fichier pour être hérité, etc... ce genre de chose.


    Voilà j'aimerais avoir comme arborescence pour mon projet:
    De ce que j'ai compris de la doc, à partir du moment où la commande "python3" est exécuté depuis le répertoire racine /src, tout devrait se dérouler sans problème...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    /src
      - main.py
      - common.py
      - package_a/
      -  - common_a.py
      -  - module_a1.py
      -  - module_a2.py
      - package_b ...
    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
    16
    17
    18
    19
    20
    21
    # main.py
    from package_a import *
    c = MyClassA()
     
     
     
    # package_a/__init__.py
    __ALL__ = ["common_a", "module_a1"] 
     
     
    # package_a/common_a.py
    class MyBaseClassA():
    	def salut(self):
    		print("MyBaseClassA from package_a.common_a")
     
     
    #package_a/module_a1.py
    from common_a import *
    class MyClassA(MyBaseClassA):
    	def salut(self):
    		print("MyClassA from module_a1 who inherits from MyBaseClassA defined in package_a.common_a")


    Déjà, est-ce que ça vous parait être une bonne structure pour un projet python ?



    Premier point qui bloque, j'ai beau mettre des __init__.py à la racine de mes dossiers packages, en spécifiant __ALL__ = [...], l'instruction suivante (dans main.py)
    ne retourne pas d'erreur, mais rien n'est importé... quand je veux instancier une classe qui est définie dans le module A1 par exemple, il me dit que cette classe n'existe pas.

    Code sh : 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
    $ ls
    common.py  main.py  package_a  __pycache__
     
    $ ipython3
    Python 3.5.2 (default, Jul  5 2016, 12:43:10) 
    IPython 2.4.1 
     
    In [1]: from package_a import *
     
    In [2]: MyBaseClassA
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-2-71217d01a55b> in <module>()
    ----> 1 MyBaseClassA
     
    NameError: name 'MyBaseClassA' is not defined
     
    In [8]: from package_a.common_a import *
     
    In [9]: MyBaseClassA
    Out[9]: package_a.common_a.MyBaseClassA


    Qu'est-ce qu'il faut faire pour que le import * fonctionne correctement ?

  2. #2
    Membre actif
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2013
    Messages
    156
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Octobre 2013
    Messages : 156
    Points : 218
    Points
    218
    Par défaut
    Salut,

    Bon déjà un peu de lecture : http://sametmax.com/les-imports-en-python/, http://sametmax.com/pourquoi-il-faut...ort-en-python/

    Déjà, est-ce que ça vous parait être une bonne structure pour un projet python ?
    J'aurai tendance à rajouter un niveau, mais bon ça devrai fonctionner.
    -- test_imports
    |-- __init__.py
    |-- package_tout_en_haut
    | |-- __init__.py
    | |-- autre_sous_package
    | | |-- __init__.py
    | | `-- autre_module_en_bas.py
    | |-- sous_module.py
    | `-- sous_package
    | |-- __init__.py
    | |-- autre_module_en_bas.py
    | |-- autre_sous_package
    | | |-- __init__.py
    | | `-- autre_module_en_bas.py
    | |-- module_tout_en_bas.py
    | `-- test_imports
    | `-- sous_module.py
    `-- top_module.py

    Montre nous ta structure avec tes init et le contenu de tes __init__, si les init sont vide, depuis le main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from common import myFunction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from packageA.moduleA1 import myFunction

  3. #3
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Ikit Voir le message
    Premier point qui bloque, j'ai beau mettre des __init__.py à la racine de mes dossiers packages, en spécifiant __ALL__ = [...], l'instruction suivante (dans main.py)
    ne retourne pas d'erreur, mais rien n'est importé... quand je veux instancier une classe qui est définie dans le module A1 par exemple, il me dit que cette classe n'existe pas.
    Pour qu'il la connaisse, je dois faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from packageA import moduleA1
    "from packageA import *" créera une variable moduleA1 associé au moduleA1.py que si vous avez écrit dans packageA/__init__.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from packageA import moduleA1
    Si packageA/__init__.py est vide, pas d'autre moyen que de faire "from packageA import moduleA1".
    Dit autrement l'association "variable moduleA1" => moduleA1.py, doit être faite. "from packageA import *" se contente de recopier les variables fabriquées par packageA/__init__.py.

    Pour plus d'infos, je vous recommande la lecture (attentive) du chapitre Packages dans le Python tutorial.

    - W
    note: Dans votre __init__.py l'instruction __ALL__ = ["common_a", "module_a1"] se contente de définir les "variables" qui seront définies lorsqu'on effectue "from .... import *". Mais en l'état, ce ne sont que des chaînes de caractères, pas encore des variables.
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Points : 69
    Points
    69
    Par défaut
    Merci pour vos réponses.

    J'ai modifié le __init__.py afin d'y ajouter les import, et ça marche mieux

    Par contre je n'arrive pas à faire fonctionner le "*"... j'ai bien vu que ça n'était pas recommandé de faire des imports *, mais j'ai pas envie de préfixer toutes mes fonctions "log, debug, etc" par common ou tool... l'idée c'est quand même d'alléger la lecture du code.

    voici actuellement à quoi ressemble mon fichier __init__ , common_a et module_a.
    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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #__init__
    #!env/python3
    # coding: utf-8
    __all__ = ["common_a", "module_a1"] 
     
    from package_a import common_a
    from package_a import module_a1
    from .common_a import *
     
     
     
    #common_a
    def MyTool():
    	print("salut")
     
    class MyBaseClassA():
    	def salut(self):
    		print("MyBaseClassA from package_a.common_a")
     
     
     
    # module_a1
    from .common_a import *
     
    class MyClassA(MyBaseClassA):
    	def salut(self):
    		print("MyClassA from module_a1 who inherits from MyBaseClassA defined in package_a.common_a")



    Quand depuis la console j'importe le package_a, l'import se passe sans erreur, et jeux utiliser les objets des modules mais uniquement en les prefixant par le nom du module,
    - common_a.MyBaseClassA
    - common_a.MyTool
    - module_a1.MyClassA

    Donc visiblement l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    from .common_a import *
    n'est pas prise en compte dans le fichier __init__, car si je fait ça direct en console ça marche bien, j'ai pas besoin ensuite de préfixer MyTool et MyBaseClassA par le nom du module...

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Dire à Python "__all__ = ["common_a", "module_a1"]" et s'étonner qu'"import *" ne trouve rien d'autre... mouais, vous n'avez pas finit d'avoir des surprises!

    Pour essayer de répondre à:
    Déjà, est-ce que ça vous parait être une bonne structure pour un projet python ?
    Vous avez déjà une structure obèse sans avoir trop écrit une seule ligne de code sinon des cut&paste pour voir.
    Personnellement, un package c'est "import package" et sa genèse est un simple "package.py".
    S'il grossit, il peut devenir package/__init__.py, a.py, b.py,... avec un split de bouts de codes dans des scripts associés.
    L'important est que l'appelant fasse toujours "import package" et d'adapter package/__init__.py pour que cette interface soit respectée.

    mais j'ai pas envie de préfixer toutes mes fonctions "log, debug, etc" par common ou tool... l'idée c'est quand même d'alléger la lecture du code.
    Les règles c'est fait pour qu'il y ait des exceptions.
    Rien ne vous interdit d'écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    import package
    from package import log, debug
    i.e. être plus sélectif sur les noms de variables que vous ajoutez à l'espace de noms du module courant.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Points : 69
    Points
    69
    Par défaut
    Dire à Python "__all__ = ["common_a", "module_a1"]" et s'étonner qu'"import *" ne trouve rien d'autre... mouais, vous n'avez pas finit d'avoir des surprises!
    Mon message n'était peut être pas assez clair.
    Mon fichier __init__.py est le suivant :
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #!env/python3
    # coding: utf-8
    __all__ = ["common_a", "module_a1"] 
     
    from package_a import common_a
    from package_a import module_a1
    from .common_a import *

    Et je disais que visiblement la dernière instruction du fichier __init__ n'est pas prise en compte... car pour moi elle aurait dû rendre accessible sans besoin de préfixer toutes les méthodes défini dans le fichier common_a... c'est du moins le comportement de la console ipython, quand on exécute à la main cette instruction.


    Vous avez déjà une structure obèse sans avoir trop écrit une seule ligne de code sinon des cut&paste pour voir.
    alors non, j'ai déjà beaucoup de code python qui est en train de s'entasser dans un ou deux scripts, et je trouve ça absolument dégueulasse... le code que je vous montre ici n'est qu'un test simplifié au maximum afin de comprendre vraiment comment fonctionne le system d'import de python, ainsi que la bonne façon de faire pour splitter son code... ça fait déjà 1 mois que je bosse sur le projet, et je trouve que j'ai déjà trop attendu avant de me pencher sérieusement sur l'organisation du code.
    Et une fois que j'aurais bien pigé ça, alors je pourrais continuer à avancer sur le projet en lui même.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Ikit Voir le message
    Et je disais que visiblement la dernière instruction du fichier __init__ n'est pas prise en compte... car pour moi elle aurait dû rendre accessible sans besoin de préfixer toutes les méthodes défini dans le fichier common_a... c'est du moins le comportement de la console ipython, quand on exécute à la main cette instruction.
    Et moi je vous disais de commencer par virer le __ALL__

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France

    Informations forums :
    Inscription : Décembre 2004
    Messages : 134
    Points : 69
    Points
    69
    Par défaut
    ouah ! ça y est tout marche comme désiré
    Bon donc en fait le __all__ ne sert à rien... ^_^° curieux car tout le monde en parle pourtant, c un reliquat de python 2 ?


    En tout cas, merci pour ta patience et ton aide wiztricks

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    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 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par Ikit Voir le message
    Bon donc en fait le __all__ ne sert à rien... ^_^° curieux car tout le monde en parle pourtant, c un reliquat de python 2 ?
    Le __ALL__ fonctionne c'est d'ailleurs à cause de ce que vous y avez mis dedans qu'il y a problème.
    Mais, il vous faut prendre le temps de relire la documentation pour comprendre comment il fonctionne.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment organiser ma solution .Net ?
    Par korrigan dans le forum Débuter
    Réponses: 1
    Dernier message: 17/04/2009, 14h56
  2. [VS2005] comment organiser une solution avec plusieurs classes
    Par mahboub dans le forum Visual Studio
    Réponses: 1
    Dernier message: 15/04/2008, 10h49
  3. comment organiser une solution sous VS
    Par mahboub dans le forum Débuter
    Réponses: 4
    Dernier message: 09/04/2008, 18h32
  4. [IMPORTANT!] Comment organiser ses recherches
    Par Emmanuel Lecoester dans le forum Firebird
    Réponses: 0
    Dernier message: 29/07/2005, 13h47

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