web-dev-qa-db-fra.com

Comment importer des packages de variables dans Python comme utiliser des variables variables ($$) en PHP?

Je veux importer un paquet en fonction de la valeur choisie par l'utilisateur.

La valeur par défaut est file1.py:

from files import file1

Si l'utilisateur choisit file2, ça devrait être :

from files import file2

En PHP, je peux le faire en utilisant variables variables :

$file_name = 'file1';
include($$file_name);
$file_name = 'file2';
include($$file_name);

Comment puis-je faire cela en Python?

36
skargor

Python n'a pas de fonctionnalité directement équivalente aux "variables variables" de PHP. Pour obtenir la valeur d'une "variable variable" (ou la valeur de toute autre expression), vous pouvez utiliser la fonction eval.

foo = "Hello World"
print eval("foo")

Cependant, cela ne peut pas être utilisé dans une instruction import.

Il est possible d'utiliser le __import__ fonction à importer à l'aide d'une variable.

package = "os"
name = "path"

imported = getattr(__import__(package, fromlist=[name]), name)

est équivalent à

from os import path as imported
55
Jeremy Banks

Vieux fil, mais j'avais besoin de la réponse, donc quelqu'un d'autre pourrait encore ...

Il existe une façon plus propre de le faire dans Python 2.7+:

import importlib


my_module = importlib.import_module("package.path.%s" % module_name)
35
Dan Copeland

Comme Fredrik Lundh déclare:

Quoi qu'il en soit, voici comment fonctionnent ces instructions et fonctions:

import X Importe le module X et crée une référence à ce module dans l'espace de noms courant. En d'autres termes, après avoir exécuté cette instruction, vous pouvez utiliser X.name Pour faire référence aux éléments définis dans le module X.

from X import * Importe le module X et crée des références dans l'espace de noms courant à tous les objets publics définis par ce module (c'est-à-dire tout ce qui n'a pas de nom commençant par "_"). Ou en d'autres termes, après avoir exécuté cette instruction, vous pouvez simplement utiliser un nom simple pour faire référence aux éléments définis dans le module X. Mais X lui-même n'est pas défini, donc X.name Ne fonctionne pas. Et si le nom était déjà défini, il est remplacé par la nouvelle version. Et si le nom en X est changé pour pointer vers un autre objet, votre module ne le remarquera pas.

from X import a, b, c Importe le module X et crée des références dans l'espace de noms courant aux objets donnés. Autrement dit, vous pouvez maintenant utiliser a et b et c dans votre programme.

Enfin, X = __import__(‘X’) fonctionne comme import X, À la différence près que 1) vous passez le nom du module sous forme de chaîne et 2) l'affectez explicitement à un variable dans votre espace de noms actuel.

Et d'ailleurs, c'est la dernière méthode qui vous intéresse.

Écrivez simplement (par exemple):

var = "datetime"
module = __import__(var)
28
Gandi

C'est probablement une très mauvaise idée de laisser l'utilisateur choisir quoi importer. Les packages peuvent exécuter du code lors de l'importation, vous autorisez donc efficacement un utilisateur à exécuter arbitrairement du code sur votre système! Beaucoup plus sûr de faire quelque chose comme

if user_input == 'file1.py':
  from files import file1 as file
Elif user_input == 'file2.py':
  from files import file2 as file
else:
  file = None
  print "Sorry, you can't import that file"
4
mattjbray

En me basant sur la réponse de mattjbray:

from importlib import import_module

# lookup in a set is in constant time
safe_names = {"file1.py", "file2.py", "file3.py", ...}

user_input = ...

if user_input in safe_names:
    file = import_module(user_input)
else:
    print("Nope, not doing this.")

Enregistre quelques lignes de code et vous permet de définir safe_names par programme, ou chargez plusieurs modules et affectez-les à un dict, par exemple.

3
sleblanc