1
votes

Échec de l'importation du module python à partir d'un répertoire différent

J'ai cette structure de code en python3:

from ..datalake.utils import utils

Tous les fichiers init__.py sont vides.

Mon problème est de savoir comment importer le module datalake à partir de tests / demo.py ? J'ai essayé à partir d'utils d'importation datalake.utils dans demo.py mais lorsque j'exécute python tests / demo.py à partir de la ligne de commande, j'obtiens ceci error ModuleNotFoundError: Aucun module nommé 'datalake' .

Si j'utilise ce code:

- datalake
  __init__.py
  utils
     __init__.py
     utils.py
  lambdas
     __init__.py
     my-lambdas.py
- tests
    __init__.py
    demo.py

J'obtiendrai une erreur ValueError: tentative d'importation relative au-delà du package de niveau supérieur .

J'ai aussi essayé d'importer le module utils du fichier my-lambda.py qui a également échoué. Le code dans my-lambda.py est de datalake.utils import utils mais j'obtiens une erreur ModuleNotFoundError: aucun module nommé 'datalake' lors de l'exécution python datalake / lambda / my-lambda.py depuis la ligne de commande.

Comment puis-je importer le module?


2 commentaires

Le répertoire parent (celui contenant à la fois la base de données et les tests) est-il sur votre PYTHONPATH? Je pense que si c'est le cas, il devrait trouver le module.


Ce n'est pas. Dois-je ajouter le chemin sur PYTHONPATH comme variable d'environnement?


4 Réponses :


-1
votes

vous pouvez essayer d'exécuter:

python -m datalake.lambda.my-lambda

suivre: https://docs.python.org/3.7/using/cmdline.html#cmdoption-m


0 commentaires

1
votes

Vous pouvez ajouter le répertoire du module dans votre sys.path :

import sys
sys.path.append("your/own/modules/folder")  # like sys.path.append("../tests")

mais c'est une méthode one-shot, qui est juste valide pour le moment, le chemin ajouté n'est pas permanent, il sera éliminé après l'exécution du code terminée.


0 commentaires

2
votes

Tout d'abord, my-lambdas.py n'est pas importable avec l'instruction import car les tirets ne sont pas valides dans les identifiants Python. Essayez de suivre les conventions de dénomination de PEP-8 a >, comme mylambdas.py .

Sinon, la structure du package semble bonne, et elle devrait être importable tant que vous êtes au niveau ci-dessus datalake / , par exemple, si vous étiez dans le répertoire myproject / ci-dessous:

myproject
├── datalake
│   ├── __init__.py
│   ├── utils.py
│   └── lambdas.py
└── tests
    ├── __init__.py
    └── demo.py

Alors cela devrait fonctionner:

XXX

Sinon, définir la variable d'environnement PYTHONPATH sur le chemin au-dessus de datalake / ou modifier sys.path sont les deux façons de changer là où Python peut importer de. Consultez le didacticiel officiel sur les modules pour plus d'informations.

Aussi quelques conseils généraux: j'ai trouvé utile de m'en tenir à des modules simples plutôt qu'à des packages (répertoires) jusqu'à ce qu'il soit nécessaire de se développer. Ensuite, vous pouvez changer foo.py dans un répertoire foo / avec un fichier __init__.py et import foo fonctionnent comme avant, même si vous devrez peut-être ajouter des importations à __init__.py pour maintenir la compatibilité de l'API. Cela vous laisserait avec une structure plus simple:

~/myproject$ python -c 'from datalake import utils'


3 commentaires

Comment exécuter les tests / demo.py à partir de la ligne de commande? Si je suis actuellement dans le répertoire myproject , exécuter python -m tests / demo me donne une erreur Aucun module nommé tests / demo .


S'il s'agit de tests unitaires, le framework de tests unitaires a souvent un exécuteur qui les découvre. Par exemple, avec pytest (ce qui est génial, btw), il vous suffit d'exécuter pytest à partir de < code> myproject / et il découvrira les fichiers correctement nommés (mais ils devraient être nommés quelque chose comme test_lambdas.py ). Si demo.py est quelque chose que vous souhaitez exécuter de manière interactive, essayez python -m tests.demo . Notez le point (. ) au lieu de la barre oblique ( / ) dans le chemin du module.


Ce ne sont pas des tests unitaires. ce sont du code de démonstration pour exécuter notre projet à partir de la ligne de commande.



2
votes

Lorsque vous exécutez une commande comme python tests / demo.py , le dossier dans lequel vous vous trouvez n'est pas ajouté au PYTHONPATH, contrairement au dossier de script. Ainsi, une importation de niveau supérieur comme import datalake échouera. Pour contourner ce problème, vous pouvez exécuter vos tests en tant que module:

Python 2:

python -m tests.demo

Python 3:

python -m tests/demo

et toute importation de datalake dans demo.py fonctionnera.

Il semble que ce que vous voulez vraiment faire est d'avoir un dossier avec des tests séparés à votre application principale et exécutez-les. Pour cela, je recommande py.test , pour votre cas, vous pouvez lire Tests en dehors du code d'application pour savoir comment le faire. TL; DR exécute vos tests à partir de votre dossier de projet de niveau supérieur avec python -m py.test et cela fonctionnera.


4 commentaires

J'ai eu cette erreur Aucun module nommé tests / demo ' lors de l'exécution de `python -m tests / demo. Dois-je changer autre chose?


@ZhaoYi êtes-vous dans le premier dossier du projet? afin que tests / demo.py existe dans le dossier dans lequel vous vous trouvez actuellement?


Oui le fichier tests / demo.py existe dans le répertoire courant qui est la racine du projet


@ZhaoYi désolé, il semble que cette syntaxe ne fonctionne qu'en python 2. utilisez plutôt python -m tests.demo .