Comment puis-je charger un module Python compte tenu de son chemin complet? Notez que le fichier peut se trouver n'importe où dans le système de fichiers, car il s'agit d'une option de configuration.
1143
Comment puis-je charger un module Python compte tenu de son chemin complet? Notez que le fichier peut se trouver n'importe où dans le système de fichiers, car il s'agit d'une option de configuration.
Réponses:
Pour l'utilisation de Python 3.5+:
Pour Python 3.3 et 3.4, utilisez:
(Bien que cela soit obsolète dans Python 3.4.)
Pour Python 2, utilisez:
Il existe des fonctions de commodité équivalentes pour les fichiers et DLL Python compilés.
Voir également http://bugs.python.org/issue21436 .
la source
__import__
.imp.load_source
définit uniquement.__name__
le module retourné. cela n'affecte pas le chargement.imp.load_source()
détermine la clé de la nouvelle entrée créée dans lesys.modules
dictionnaire, donc le premier argument affecte effectivement le chargement.imp
module est obsolète depuis la version 3.4: Leimp
package est en attente de dépréciation en faveur deimportlib
.L'avantage d'ajouter un chemin d'accès à sys.path (au lieu d'utiliser imp) est qu'il simplifie les choses lors de l'importation de plusieurs modules à partir d'un même package. Par exemple:
la source
sys.path.append
pour pointer vers un seul fichier python au lieu d'un répertoire?importlib.import_module(mod_name)
peut être utilisé à la place de l'importation explicite ici si le nom du module n'est pas connu au moment de l'exécution, j'ajouterais unsys.path.pop()
à la fin, cependant, en supposant que le code importé n'essaye pas d'importer plus de modules tel qu'il est utilisé.Si votre module de niveau supérieur n'est pas un fichier mais est empaqueté comme un répertoire avec __init__.py, alors la solution acceptée fonctionne presque, mais pas tout à fait. Dans Python 3.5+, le code suivant est nécessaire (notez la ligne ajoutée qui commence par 'sys.modules'):
Sans cette ligne, lorsque exec_module est exécuté, il essaie de lier les importations relatives de votre niveau supérieur __init__.py au nom du module de niveau supérieur - dans ce cas, "mymodule". Mais "mymodule" n'est pas encore chargé, vous obtiendrez donc l'erreur "SystemError: le module parent 'mymodule' n'est pas chargé, ne peut pas effectuer d'importation relative". Vous devez donc lier le nom avant de le charger. La raison en est l'invariant fondamental du système d'importation relatif: "La position invariante est que si vous avez sys.modules ['spam'] et sys.modules ['spam.foo'] (comme vous le feriez après l'importation ci-dessus ), ce dernier doit apparaître comme l'attribut foo du premier ", comme expliqué ici .
la source
mymodule
?/path/to/your/module/
c'est en fait/path/to/your/PACKAGE/
? etmymodule
tu veux diremyfile.py
?Pour importer votre module, vous devez ajouter son répertoire à la variable d'environnement, temporairement ou définitivement.
Temporairement
En permanence
Ajout de la ligne suivante à votre
.bashrc
fichier (sous linux) et exécutionsource ~/.bashrc
dans le terminal:Crédit / Source: saarrrr , une autre question d'échange de pile
la source
Il semble que vous ne souhaitiez pas importer spécifiquement le fichier de configuration (qui comporte de nombreux effets secondaires et complications supplémentaires), vous voulez simplement l'exécuter et pouvoir accéder à l'espace de noms résultant. La bibliothèque standard fournit une API spécifiquement pour cela sous la forme de runpy.run_path :
Cette interface est disponible dans Python 2.7 et Python 3.2+
la source
result[name]
,result.get('name', default_value)
, etc.)from runpy import run_path; from argparse import Namespace; mod = Namespace(**run_path('path/to/file.py'))
Vous pouvez également faire quelque chose comme ça et ajouter le répertoire dans lequel se trouve le fichier de configuration dans le chemin de chargement Python, puis faire juste une importation normale, en supposant que vous connaissez le nom du fichier à l'avance, dans ce cas "config".
Désordonné, mais cela fonctionne.
la source
Vous pouvez utiliser le
méthode du module imp .
la source
imp.load_dynamic(module_name, path_to_file)
pour les DLLla source
except:
clause fourre-tout est rarement une bonne idée.save_cwd = os.getcwd()
try: …
finally: os.chdir(save_cwd)
this is already addressed by the standard library
oui, mais python a la mauvaise habitude de ne pas être rétrocompatible ... comme la réponse vérifiée dit qu'il y a 2 façons différentes avant et après 3.3. Dans ce cas, je préfère écrire ma propre fonction universelle que de vérifier la version à la volée. Et oui, peut-être que ce code n'est pas trop bien protégé contre les erreurs, mais il montre une idée (qui est os.chdir (), je n'y ai pas pensé), sur la base de laquelle je peux écrire un meilleur code. D'où +1.Voici du code qui fonctionne dans toutes les versions de Python, de 2.7 à 3.5 et probablement même d'autres.
Je l'ai testé. C'est peut-être moche mais jusqu'à présent c'est le seul qui fonctionne dans toutes les versions.
la source
load_source
ne l'a pas fait car elle importe le script et fournit l'accès au script aux modules et aux globaux au moment de l'importation.J'ai trouvé une version légèrement modifiée de la merveilleuse réponse de @ SebastianRittau (pour Python> 3.4 je pense), qui vous permettra de charger un fichier avec n'importe quelle extension en tant que module en utilisant
spec_from_loader
au lieu despec_from_file_location
:L'avantage d'encoder le chemin de manière explicite
SourceFileLoader
est que la machine n'essaiera pas de comprendre le type du fichier à partir de l'extension. Cela signifie que vous pouvez charger quelque chose comme un.txt
fichier à l'aide de cette méthode, mais vous ne pouvez pas le fairespec_from_file_location
sans spécifier le chargeur car il.txt
n'est pas dansimportlib.machinery.SOURCE_SUFFIXES
.la source
Voulez-vous dire charger ou importer?
Vous pouvez manipuler la
sys.path
liste, spécifier le chemin d'accès à votre module, puis importer votre module. Par exemple, étant donné un module à:Vous pourriez faire:
la source
sys.path[0:0] = ['/foo']
Explicit is better than implicit.
Alors pourquoi pas à lasys.path.insert(0, ...)
place desys.path[0:0]
?Je pense que vous pouvez utiliser
imp.find_module()
etimp.load_module()
charger le module spécifié. Vous devrez séparer le nom du module du chemin d'accès, c'est-à-dire que si vous souhaitez charger,/home/mypath/mymodule.py
vous devrez faire:... mais cela devrait faire le travail.
la source
Vous pouvez utiliser le
pkgutil
module (en particulier lawalk_packages
méthode) pour obtenir une liste des packages dans le répertoire courant. De là, il est trivial d'utiliser laimportlib
machinerie pour importer les modules que vous souhaitez:la source
Créer le module python test.py
Créer le module python test_check.py
Nous pouvons importer le module importé depuis le module.
la source
Cette zone de Python 3.4 semble être extrêmement tortueuse à comprendre! Cependant, avec un peu de piratage en utilisant le code de Chris Calloway pour commencer, j'ai réussi à faire fonctionner quelque chose. Voici la fonction de base.
Cela semble utiliser des modules non obsolètes de Python 3.4. Je ne prétends pas comprendre pourquoi, mais cela semble fonctionner à partir d'un programme. J'ai trouvé que la solution de Chris fonctionnait sur la ligne de commande mais pas depuis l'intérieur d'un programme.
la source
Je ne dis pas que c'est mieux, mais par souci d'exhaustivité, je voulais suggérer la
exec
fonction, disponible en python 2 et 3.exec
vous permet d'exécuter du code arbitraire dans la portée globale ou dans une portée interne, fourni sous forme de dictionnaire.Par exemple, si vous avez un module stocké dans
"/path/to/module
"avec la fonctionfoo()
, vous pouvez l'exécuter en procédant comme suit:Cela rend un peu plus explicite le chargement dynamique du code et vous accorde une puissance supplémentaire, telle que la possibilité de fournir des fonctions intégrées.
Et si avoir accès via des attributs, au lieu de clés est important pour vous, vous pouvez concevoir une classe de dict personnalisée pour les globaux, qui fournit un tel accès, par exemple:
la source
Pour importer un module à partir d'un nom de fichier donné, vous pouvez temporairement étendre le chemin d'accès et restaurer le chemin d'accès système dans la référence de bloc finalement :
la source
Si nous avons des scripts dans le même projet mais dans des répertoires différents, nous pouvons résoudre ce problème par la méthode suivante.
Dans cette situation ,
utils.py
est ensrc/main/util/
la source
Cela devrait fonctionner
la source
name, ext = os.path.splitext(os.path.basename(infile))
. Votre méthode fonctionne car la restriction précédente à l'extension .py. En outre, vous devriez probablement importer le module dans une entrée de variable / dictionnaire.J'ai fait un package qui utilise
imp
pour vous. Je l'appelleimport_file
et voici comment il est utilisé:Vous pouvez l'obtenir à:
http://pypi.python.org/pypi/import_file
ou à
http://code.google.com/p/import-file/
la source
Importer des modules de package lors de l'exécution (recette Python)
http://code.activestate.com/recipes/223972/
la source
Sous Linux, l'ajout d'un lien symbolique dans le répertoire où se trouve votre script python fonctionne.
c'est à dire:
python créera
/absolute/path/to/script/module.pyc
et le mettra à jour si vous modifiez le contenu de/absolute/path/to/module/module.py
incluez ensuite les éléments suivants dans mypythonscript.py
la source
git
et en vérifiant votregit status
pour vérifier que vos modifications apportées au script sont effectivement en train de revenir au document source et ne se perdent pas dans l'éther.J'ai écrit ma propre fonction d'importation globale et portable, basée sur le
importlib
module, pour:sys.path
ou sur un stockage de chemin de recherche.Les exemples de structure de répertoires:
Dépendance et ordre d'inclusion:
La mise en oeuvre:
Dernier magasin de modifications: https://sourceforge.net/p/tacklelib/tacklelib/HEAD/tree/trunk/python/tacklelib/tacklelib.py
test.py :
testlib.py :
testlib.std1.py :
testlib.std2.py :
testlib.std3.py :
Sortie (
3.7.4
):Testé en Python
3.7.4
,3.2.5
,2.7.16
Avantages :
testlib.std.py
astestlib
,testlib.blabla.py
astestlib_blabla
et ainsi de suite).sys.path
ou d'un stockage de chemin de recherche.SOURCE_FILE
etSOURCE_DIR
entre les appels àtkl_import_module
.3.4.x
et supérieur] Peut mélanger les espaces de noms de module dans destkl_import_module
appels imbriqués (ex:named->local->named
oulocal->named->local
et ainsi de suite).3.4.x
et supérieur] Peut exporter automatiquement les variables / fonctions / classes globales d'où elles sont déclarées à tous les modules enfants importés viatkl_import_module
(via latkl_declare_global
fonction).Inconvénients :
3.3.x
et inférieur] Obligation de déclarertkl_import_module
dans tous les modules qui appelletkl_import_module
(duplication de code)Mise à jour 1,2 (pour
3.4.x
et supérieur uniquement):Dans Python 3.4 et supérieur, vous pouvez contourner l'exigence de déclaration
tkl_import_module
dans chaque module en déclaranttkl_import_module
dans un module de niveau supérieur et la fonction s'injecterait à tous les modules enfants en un seul appel (c'est une sorte d'importation auto-déployée).Mise à jour 3 :
Ajout d'une fonction
tkl_source_module
analogique à bashsource
avec prise en charge de l'exécution lors de l'importation (implémentée via la fusion du module au lieu de l'importation).Mise à jour 4 :
Ajout d'une fonction
tkl_declare_global
pour exporter automatiquement une variable globale de module vers tous les modules enfants où une variable globale de module n'est pas visible car ne fait pas partie d'un module enfant.Mise à jour 5 :
Toutes les fonctions ont été déplacées dans la bibliothèque tacklelib, voir le lien ci-dessus.
la source
Il existe un package spécifiquement dédié à cela:
Il est testé sur toutes les versions de Python (Jython et PyPy aussi), mais il peut être excessif en fonction de la taille de votre projet.
la source
Ajout de cela à la liste des réponses car je n'ai rien trouvé qui fonctionnait. Cela permettra d'importer des modules python compilés (pyd) en 3.4:
la source
manière assez simple: supposons que vous vouliez importer un fichier avec un chemin relatif ../../MyLibs/pyfunc.py
Mais si vous le faites sans gardien, vous pouvez enfin obtenir un très long chemin
la source
Une solution simple utilisant à la
importlib
place duimp
package (testée pour Python 2.7, bien qu'elle devrait également fonctionner pour Python 3):Vous pouvez maintenant utiliser directement l'espace de noms du module importé, comme ceci:
L'avantage de cette solution est que nous n'avons même pas besoin de connaître le nom réel du module que nous souhaitons importer , pour l'utiliser dans notre code. Ceci est utile, par exemple dans le cas où le chemin du module est un argument configurable.
la source
sys.path
, qui ne convient pas à tous les cas d'utilisation.sys.path.pop()
Cette réponse est un complément à la réponse de Sebastian Rittau répondant au commentaire: "mais si vous n'avez pas le nom du module?" C'est un moyen rapide et sale d'obtenir le nom probable du module python avec un nom de fichier - il monte simplement dans l'arborescence jusqu'à ce qu'il trouve un répertoire sans
__init__.py
fichier, puis le retourne en nom de fichier. Pour Python 3.4+ (utilise pathlib), ce qui est logique puisque les utilisateurs de Py2 peuvent utiliser "imp" ou d'autres façons de faire des importations relatives:Il existe certainement des possibilités d'amélioration, et les
__init__.py
fichiers optionnels peuvent nécessiter d'autres modifications, mais si vous en avez__init__.py
en général, cela fait l'affaire.la source
La meilleure façon, je pense, est de la documentation officielle ( 29.1. Imp - Accéder aux importations internes ):
la source