web-dev-qa-db-fra.com

Importer un fichier en utilisant string comme nom

Duplicate possible:
Importation de module dynamique en Python

J’ai l’intention de créer très bientôt une suite de fichiers, et le meilleur moyen de l’organiser est d’avoir une liste, celle-ci se trouvant tout en haut du fichier, et après cela, une quantité de code ridicule à gérer. ce que cette liste contrôle et comment elle fonctionne. Je cherche à écrire ladite liste une seule fois, et ladite liste est une liste de noms de dossiers et de fichiers dans ce format:

[(folder/filename, bool, bool, int), (folder/filename, bool, bool, int)]

Comme vous pouvez le constater, folder/filename sont les mêmes (en quelque sorte). Le nom de fichier est le nom du dossier avec .py à la fin, mais pour importer XXX, vous n'avez pas besoin d'importer XXX.py, je ne vois donc pas cela causer de problème.

Le problème auquel je suis confronté est d'importer en utilisant cette méthode ...

for (testName, auto, hardware, bit) in testList:
    print(testName)
    paths = "\\" + testName
    print paths
    addpath(paths)
    sys.modules[testName] = testName # One of a few options I've seen suggested on the net
    print("Path Added")
    test = testName + ".Helloworld()"
    eval(test)

Donc, pour chaque test que j'ai, imprimez le nom, assemblez une chaîne qui contient le chemin ("\\testName"), pour cet exemple, imprimez le chemin du test, puis ajoutez le chemin à la liste (sys.path.append(path)), puis imprimez pour confirmer que cela s'est produit, assembler une chaîne qui sera exécutée par eval pour le module principal de tests et éventuellement l’évaluer.

Comme vous pouvez le constater, il me faut actuellement une liste d'importations en haut. Je ne peux pas simplement importer testName (le contenu de testName est le nom du module que je souhaite importer), car il essaiera de trouver un module appelé testName et non un module appelé le contenu de testName.

J'ai vu quelques exemples montrant que cela a été fait, mais je ne trouve aucun qui fonctionne dans mon cas. Si quelqu'un pouvait littéralement lancer un morceau de code qui le fait, ce serait merveilleux.

Je demanderais également que je ne sois pas suspendu, dessiné ni coupé pour utiliser eval, il est utilisé dans un environnement très contrôlé (la liste par laquelle il fait défiler se trouve dans le fichier .py, de sorte qu'aucun "utilisateur final" ne devrait avec ça).

12
XtrmJosh

Je ne sais pas si j'ai tout compris correctement, mais vous pouvez importer un module de manière dynamique à l'aide de __import__:

mod = __import__(testName)
mod.HelloWorld()

Edit : Je ne savais pas que l'utilisation de __import__ était découragée par la documentation python pour le code utilisateur: __import__ documentation (comme noté par Bakuriu)

Cela devrait également fonctionner et serait considéré comme meilleur style:

import importlib

mod = importlib.import_module(testName)
mod.HelloWorld()
30
lbonn
  1. Ne jamais, jamais, jamais jouer avec sys.modules directement si vous ne savez pas exactement ce que vous faites.
  2. Il y a beaucoup de façons de faire ce que vous voulez:
    1. La fonction __import__
    2. Utilisation de imp.load_module
    3. Utilisation de importlib.import_module

Je voudrais éviter d'utiliser __import__ directement et opter pour importlib.import_module (qui est également suggéré à la fin de la documentation de __import__).

19
Bakuriu

Ajoutez le chemin où réside le module à sys.path. Importez le module en utilisant la fonction __import__ qui accepte une variable de chaîne comme nom de module.

import sys
sys.path.insert(0, mypath)  # mypath = path of module to be imported
imported_module = __import__("string_module_name") # __import__ accepts string 
imported_module.myfunction()   # All symbols in mymodule are now available normally
0
Swapnil