Importer module local python

Le problème exposé dans ce sujet a été résolu.

Bonjour !

J’ai un problème avec un programme python : j’ai un dossier qui suit l’architecture suivante

gui > opt.py, __init__.py
utils > __init__.py, acquisition.py
__init__.py

Je souhaiterais importer les fonctions/classes dans acquisition.py dans mon fichier opt.py. J’ai essayé from ..utils.acquisition import * mais ça me renvoie No module named 'utils'.

J’ai trouvé d’autres méthodes sur stackoverflow qui utilisent le module path, mais d’après les commentaires cette méthode n’est pas très maintenable. Auriez-vous une solution à mon problème ?

Merci ^^

+0 -0

Salut,

La syntaxe que tu utilises est la bonne. Je suspecte soit que tu as une faute de frappe quelque part faisant que le nom d’un sous-module n’est pas le bon, ou bien que tu n’invoques pas Python correctement sur ton module qui englobe les autres.

Pour illustration, ceci fonctionne :

$ tree zds
zds
├── gui
│   └── opt.py
└── utils
    └── acquisition.py

3 directories, 2 files
$ cat zds/utils/acquisition.py
FOO = "foo"
$ cat zds/gui/opt.py
from ..utils.acquisition import FOO
$ python -c "from zds.gui import opt;print(opt.FOO)"
foo

PS : tu n’as pas besoin du __init__.py dans les sous-modules, mais ils ne font pas de mal non plus. Et par ailleurs évite les imports globaux (les from ... import *) au maximum : garder les imports explicites et bien rangés dans des namespaces rend les choses plus simples lorsque les projets grandissent.

+2 -0

Merci pour ta réponse !

J’ai refait le test chez moi et c’est bien la manière dont j’appelle python qui pause problème. ;)

Cela m’amène donc à d’autres questions malheuresement… Je ne comprends pas pourquoi il est nécessaire de l’appeler en dehors du dossier zds pour que cela fonctionne. Dans l’idéal j’aimerais pouvoir lancer mon "opt.py" directement, sans utiliser un autre fichier qui appellerait des éléments de "opt.py".

Pour illustrer, si je suis situé à la racine de zds et que j’écris python gui/opt.py python soulève l’erreur

File "C:\[...]\zds\gui\opt.py", line 1, in <module> 
    from ..utils.acquisition import FOO
ImportError: attempted relative import with no known parent package

De même, je reçois la même erreur si je crée un fichier main.py à la racine de zds avec

zds
├── gui
│   └── opt.py
├── utils
│    └── acquisition.py
└── main.py

et comme code

from gui import opt

print(opt.FOO)

Je note bien ton PS également, merci beaucoup :)

Cela m’amène donc à d’autres questions malheuresement… Je ne comprends pas pourquoi il est nécessaire de l’appeler en dehors du dossier zds pour que cela fonctionne. Dans l’idéal j’aimerais pouvoir lancer mon "opt.py" directement, sans utiliser un autre fichier qui appellerait des éléments de "opt.py".

Ça vient de la façon dont les modules sont conçus en Python (et dans la plupart des langages de programmations qui ont un concept similaire). Si Python ne voit pas l’ensemble du module, les imports relatifs ne peuvent pas fonctionner.

Tes questions en soulèvent certaines de mon côté. Est-ce que tu pourrais expliquer ce que tu voudrais que python gui/opt.py ou encore python main.py fassent concrètement ? Avec un exemple de code ? Classiquement, ce que tu demandes est résolu par la définition de point d’entrées (entry points en anglais) qui peuvent être défini dans le fichier pyproject.toml qui décrit les métadonnées de ton package. Mais je me dit que tu as peut être un problème de conception quelque part si tu veux pouvoir appeler arbitrairement n’importe quel sous-module comme des programmes isolés.

Pour répondre à ta question, j’ai programmé un algorithme d’optimisation qui devrait être utilisable par des non-utilisateurs de python. Je voulais avoir un dossier gui avec le code de l’interface qui appelle les fonctions d’optimisation situées dans utils, pour bien séparer les deux parties de mon code !

Le main utilisera les modules d’interfaces de gui (qui utilisent utils). J’ai le sentiment qu’il vaudrait peut-être mieux que je mette mes fichiers gui dans la racine avec main, j’avoue que c’est la première fois que je fais ce genre de chose en python.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte