[Python] Résolution du problème d'importation dû à la différence des points d'entrée

Lors de l'exécution depuis le point d'entrée de l'application elle-même, même s'il n'y a pas de problème d'exécution Lorsque j'ai démarré chaque fichier de module comme point d'entrée, je suis parfois tombé sur l'instruction d'importation, alors j'ai étudié la solution.

--6 / 12: Correction car sauf dans try ~ except que l'instruction était catch.

l'importation démarre à partir du répertoire utilisé comme point d'entrée

À titre d'exemple, considérez la structure de répertoires / fichiers suivante.

main.py ...Fichier d'exécution en tant qu'application
|
|--[src] ...Répertoire de stockage des modules
    |
    |-- module1.py ... main.Module appelé depuis py
    |-- module2.py ... module1.Module appelé depuis py

Si le point d'entrée en tant qu'application est main.py, seul le répertoire contenant main.py sera reconnu comme chemin python. Par conséquent, tous les fichiers qui composent cette application doivent être importés à partir du répertoire où se trouve main.py. En d'autres termes, si vous souhaitez utiliser module1.py vers module2.py dans la structure de répertoires ci-dessus,

/src/module1.py


# -*- coding: utf-8 -*-

import module2 # ImportError!

Alors non

/src/module1.py


# -*- coding: utf-8 -*-

import src.module2 # OK

Doit être.

Impossible de démarrer à partir de fichiers dans le répertoire src

Cette description convient parfaitement, mais des problèmes surviennent lors de l'écriture du code de test dans module1.py.

Le code de test ici est censé vérifier le fonctionnement des classes et des fonctions dans module1.py. N'est-ce pas assez courant d'écrire un code simple qui appelle une fonction dans le fichier et d'appuyer sur la touche F5 pour voir le comportement du code que vous avez écrit sur place?

Cependant, si vous écrivez ʻimport src.module2, lorsque vous démarrez le programme avec module1.py comme point d'entrée, la partie srcne peut pas être reconnue et une erreur d'importation se produira. Cela est dû au fait que le répertoire d'exécution lors du démarrage de module1.py passe au répertoire src. Il n'y a pas de répertoire appelésrc` dans le répertoire src.

Dans cet article, je vais vous montrer trois idées qui résolvent ce problème et vous permettent de lancer le programme à partir de main.py ou module1.py. À propos, tous ont des inconvénients et ce n'est pas OK si vous faites cela. Nous recherchons un moyen plus intelligent, alors veuillez commenter

--Comment faire sys.path.append () dans le fichier du module -Comment sys.path.append () avec \ _ \ _ init \ _ \ _.py --Comment attraper ImportError et branch

Comment sys.path.append () dans le fichier du module

C'est une solution en écrivant sys.path.append () dans module1.py. Je pense que c'est une méthode assez courante.

/src/module1.py


# -*- coding: utf-8 -*-

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))
import module2

Il s'agit d'ajouter le répertoire contenant le fichier module1.py au chemin python. Faire cela ajoutera le répertoire src au chemin python et l'erreur ne se produira pas même si l'instruction d'importation n'a pas src. En d'autres termes, il vous suffit d'importer module2.py avec ʻimport module2`.

Cependant, cette méthode pose le problème que s'il existe un grand nombre de fichiers de module, la description ci-dessus pour chaque fichier est requise. De plus, sys.path.append () est reflété dans tous les fichiers utilisant module1.py, qui pollue l'espace de noms. (Vous pourrez créer ʻimport module 2` dans main.py.)

Comment sys.path.append () avec \ _ \ _ init \ _ \ _.py

C'est une méthode pour placer \ _ \ _ init \ _ \ _. Py directement sous le répertoire src et y effectuer sys.path.append (). Dans ce cas, la structure du répertoire ressemble à ceci:

main.py ...Fichier d'exécution en tant qu'application
|
|--[src] ...Répertoire de stockage des modules
    |
    |-- __init__.py ... sys.path.append()Fichier à exécuter
    |-- module1.py ... main.Module appelé depuis py
    |-- module2.py ... module1.Module appelé depuis py

En outre, le contenu de \ _ \ _ init \ _ \ _. Py est le suivant.

/src/__init__.py


# -*- coding: utf-8 -*-

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '.'))

Ce que cela fait, c'est que lorsque vous faites ʻimport src.module1 dans main.py, \ _ \ _ init \ _ \ _. Py est également importé implicitement. Plus précisément, lors de l'exécution de ʻimport src.module1 depuis main.py, cela fonctionne de sorte que \ _ \ _ init \ _ \ _. Py soit importé en premier, puis module1.py est importé. Je vais. pour cette raison,

  1. Lors de l'importation de \ _ \ _ init \ _ \ _. Py, le sys.path.append () ci-dessus est exécuté et le répertoire src est ajouté au chemin python.
  2. module1.py est importé, mais comme le répertoire src a déjà été ajouté au chemin, module2.py peut être importé en spécifiant ʻimport module2`.

Ce sera l'opération. De cette façon, vous pouvez réduire la quantité de code car chaque module du répertoire src n'a pas besoin de sys.path.append ().

Cependant, tant que vous utilisez sys.path.append (), le problème de la pollution des espaces de noms demeure.

Comment attraper ImportError et branch

C'est une méthode pour intercepter ImportError et changer dynamiquement la destination d'importation sans utiliser sys.path.append (). Plus précisément, le code est le suivant.

/src/module1.py


# -*- coding: utf-8 -*-

try:
    import src.module2 # main.Si vous partez de py, cela sera exécuté
except ImportError:
    import module2 # module1.Si vous partez de py, cela sera exécuté

Si ʻimport src.module2 échoue, ʻimport module2 est exécuté à la place. Normalement, l'application s'exécute à partir de main.py, vous pouvez donc voir le répertoire src à partir du répertoire d'exécution. Par conséquent, au démarrage de main.py, le contenu du bloc try sera exécuté sans aucun problème.

D'un autre côté, si vous démarrez module1.py comme point d'entrée, vous obtiendrez une ImportError car vous ne pouvez pas voir le répertoire src. Par conséquent, interceptez ImportError dans le bloc except et modifiez la description de la destination d'importation afin qu'elle puisse être importée avec succès.

Cette technique n'utilise pas sys.path.append () donc elle ne pollue pas l'espace de noms.

Cependant, le problème d'avoir à ajouter la description ci-dessus à chaque fichier de module demeure.

Résumé

Dans cet article, je vous ai montré trois façons de lancer un programme à partir de main.py ou module1.py.

--Comment faire sys.path.append () dans le fichier du module -Comment sys.path.append () avec \ _ \ _ init \ _ \ _.py --Comment attraper ImportError et branch

Cependant, il y a des inconvénients à chaque méthode, je me demande donc s'il est nécessaire de les utiliser correctement en fonction de l'environnement.

Recommended Posts

[Python] Résolution du problème d'importation dû à la différence des points d'entrée
Différence d'ID d'objet due à l'importation en Python
Dans la commande python, python pointe vers python3.8
Trouver des erreurs en Python
Le 15e comment écrire un problème de référence en temps réel hors ligne en Python
Le 14ème problème de référence d'écriture en temps réel hors ligne en python
Le 18ème comment écrire un problème de référence en temps réel hors ligne en Python
Résolvez le problème maximum de sous-tableau en Python
17ème problème de référence d'écriture en temps réel hors ligne implémenté en Python
Comment obtenir la différence de date et d'heure en secondes avec Python
Le nom du fichier était mauvais en Python et j'étais accro à l'importation
Comment utiliser la bibliothèque C en Python
Calculons en fait le problème statistique avec Python
Essayez de résoudre le problème de l'héritage de classe Python
Résumé de la façon d'importer des fichiers dans Python 3
La première étape du problème de réalisation des contraintes en Python
Pour remplacer dynamiquement la méthode suivante en python
À propos de la différence entre "==" et "is" en python
Dessinez des graphiques dans Julia ... Laissez les graphiques à Python
Le 18ème problème d'écriture en temps réel hors ligne en Python
Conseils pour rédiger un aplatissement concis en python
Comment obtenir les fichiers dans le dossier [Python]
Résolution d'équations de mouvement en Python (odeint)
Le 19ème problème d'écriture en temps réel hors ligne en Python
Résolvez le problème du sac à dos Python avec l'algorithme glouton
Je veux afficher la progression en Python!
J'ai essayé de représenter graphiquement les packages installés en Python
Comment obtenir le nom de la variable lui-même en python
Informations de base Écrire le problème d'algorithme de l'automne 2018 en Python
Comment obtenir le nombre de chiffres en Python
[Python] Essayez de lire la bonne réponse au problème FizzBuzz
Comment connaître le répertoire actuel en Python dans Blender
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
[Réintroduction à python] Comment importer via le répertoire parent
Convertissez l'image au format .zip en PDF avec Python
Je veux juste trouver l'intervalle de confiance à 95% de la différence de ratio de population en Python
Je veux écrire en Python! (3) Utiliser des simulacres
Comment utiliser le modèle appris dans Lobe en Python
J'ai essayé de résoudre le problème avec Python Vol.1
[Python] Comment afficher les valeurs de liste dans l'ordre
Pour faire l'équivalent de Ruby ObjectSpace._id2ref en Python
Je veux utiliser le jeu de données R avec python
Python Open CV a essayé d'afficher l'image sous forme de texte.
2015-12-26 python2> datetime> Implémentation pour prendre la différence en secondes entre deux chaînes datetime au format ISO> Utiliser .seconds ()
[Python] Lorsque vous souhaitez importer et utiliser votre propre package dans le répertoire supérieur
[python] Comment vérifier si la clé existe dans le dictionnaire
Sortie "Dessiner fougère par programmation" dans le processus de dessin en Python
Comment déboguer une bibliothèque Python standard dans Visual Studio
Comment importer la bibliothèque Python configurée dans EFS dans Lambda
Comment utiliser la méthode __call__ dans la classe Python
Changer la destination de sortie standard en un fichier en Python
Comment importer des fichiers où vous le souhaitez en Python
Différentes façons de calculer la similitude entre les données avec python
[Note] Importation de fichiers dans le répertoire parent en Python
Comment obtenir la dernière (dernière) valeur d'une liste en Python
Obtenez la date et l'heure actuelles en Python, en tenant compte du décalage horaire
J'ai essayé d'implémenter la fonction d'envoi de courrier en Python