Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Imports de modules perso

+4 votes

J'ai un projet avec une arborescence comme suit :

Projet
├── main.py
├── src
   ├── __init__.py
   ├── foo.py
   ├── bar.py

Dans mon main.py :

from src.bar import afficher
afficher()

Dans foo.py :

def test(str):
    return("Test de la "+str)

Et dans bar.py :

from foo import test
def afficher():
    print(test("Fonction"))

if __name__ == "__main__":
    afficher()

Quand je lance directement bar.py pour le tester, cela fonctionne.
Cependant quand je lance mon main.py, je me mange un

ImportError : No module named 'foo'

En remplaçant "from foo" par "from .foo" cela fonctionne, mais c'est le fichier bar.py que je ne peux plus lancer directement.
J'aimerais pouvoir garder le test au sein du fichier bar.py, tout en pouvant lancer mon programme depuis main.py. Peut-être n'ai-je pas opté pour la bonne organisation de fichiers ?

Merci d'avance

demandé 4-Oct-2015 par Zara (200 points)

2 Réponses

+2 votes
 
Meilleure réponse

Je ne crois pas qu'il y ait une bonne façon de faire les choses en python (contrairement au JAVA par ex où on est presque forcé à bien structuré selon une norme à la con sinon tu te fais buter par les forumeurs / IDE's)

Une approche possible pour bien gérer l'organisation de ses fichiers:

mon_application/
  mon_module_1/
    ab.py
    bc.by
    test/ 
      test_cd.py
      test_bc.py
  mon_module_2/
    cd.py
    de.py
    test/
      test_cd.py
      test_de.py
  ee.py
  ff.py
  __init__.py
  __main__.py
  test/
    test_ee.py
    test_ff.py

sources/lectures : linuxfr, docs python-guide, SO, open-source python the right way

ps : J'ai l'impression que personne n'est d'accord pour une même architecture, chaque blog/expert/amateur propose sa propre sauce ... Donc tu devrais un peu chercher sur net et voir ce qui te convient le mieux en fonction de ton projet (si tu proj tient sur un fichier ou sur plusieurs, si ya du web ou pas ...) avec des googling de ce genre

pss : Une autre option est d'aller chercher des repôts populaires codés en python sur github pour s'en inspirer, notamment s'inspirer de la structure de leur appli, les tests unitaires, les imports de modules ..

répondu 5-Oct-2015 par boblinux (3,092 points)
sélectionné 6-Oct-2015 par Zara

J'ai googlé et regardé sur github et les gros projets semblent utiliser quelque chose de très similaire à ce que tu me proposes, sauf pour les test qui sont regroupés dans un dossier hors de mon_application.
Bref, j'adopte !!
Merci bien :)

+2 votes

Je n'ai pas une grosse expérience des tests unitaires en python, mais ce n'est pas ainsi que je ferais les choses.

D'abord, je m'arrangerais que les tests soient dans un fichier dédié.
Sinon, je les écrirais de telle manière qu'ils soient encapsulés dans une classe ou une fonction à l'interface convenue, appelable depuis le main (ou un script dédié au même niveau de l'arborescence) quand on lui demande explicitement de lancer les tests unitaires.

De plus, l'actuel import de foo.test dans bar.py est faux :

from src.foo import test  # !
def afficher():
    print(test("Fonction"))

if __name__ == "__main__":  # ceci est à encapsuler dans une classe/fonction
    afficher()

Cela semble plus logique, d'après l'architecture de ton package.

Enfin, je changerais la structure en quelque chose comme cela, avec le main suivant la convention usuelle du main de module :

Projet
├── nom_du_projet
   ├── __main__.py
   ├── __init__.py
   ├── foo.py
   ├── bar.py

Cela permet notamment de lancer le main avec la commande python -m nom_du_projet, ce qui est classe et bien packagé.

Une ressource intéressante qui permet de mettre des tests en branle rapidement : pytest, abordé dans la partie 3 du tuto tests unitaires de sametmax.

répondu 4-Oct-2015 par lucas (2,308 points)

Merci beaucoup, j'étais passé à côté du tuto de s&m, ça va bien m'aider !!

...