En python, je dois instancier une certaine classe, connaissant son nom dans une chaîne, mais cette classe «vit» dans un module importé dynamiquement. Un exemple suit:
script de classe chargeur:
import sys
class loader:
def __init__(self, module_name, class_name): # both args are strings
try:
__import__(module_name)
modul = sys.modules[module_name]
instance = modul.class_name() # obviously this doesn't works, here is my main problem!
except ImportError:
# manage import error
un script de module chargé dynamiquement:
class myName:
# etc...
J'utilise cet arrangement pour faire en sorte que n'importe quel module chargé dynamiquement soit utilisé par la classe loader suivant certains comportements prédéfinis dans les modules chargés dynamiquement ...
module = __import__(module, fromlist=[name])
a seulement fonctionné pour moi.obj.__module__
importlib.import_module
chargera le fichier .py dans un pyc si nécessaire et gérera le module.name.pathing.to.get.to. the class.__import__
ne fera ni l'une ni l'autre de ces choses, dans un environnement django (non testé en dehors de cela)tl; dr
Importez le module racine avec
importlib.import_module
et chargez la classe par son nom en utilisant lagetattr
fonction:explications
Vous ne souhaitez probablement pas utiliser
__import__
pour importer dynamiquement un module par nom, car cela ne vous permet pas d'importer des sous-modules:Voici ce que dit la documentation python
__import__
:À la place, utilisez le
importlib
module standard pour importer dynamiquement un module par nom. Avecgetattr
vous pouvez alors instancier une classe par son nom:Vous pouvez également écrire:
Ce code est valide en python ≥ 2.7 (y compris python 3).
la source
mod = __import__("os.path"); mod.join
contrairement à ce qui suit:mod = importlib.import_module("os.path"); mod.join
Utilisez
getattr
pour obtenir un attribut à partir d'un nom dans une chaîne. En d'autres termes, obtenez l'instance commela source
Copier-coller un extrait:
la source
Si vous voulez que cette phrase
from foo.bar import foo2
soit chargée dynamiquement, vous devez le fairela source
On peut simplement utiliser la
pydoc.locate
fonction.la source
Je ne pouvais pas vraiment y arriver dans mon cas d'utilisation à partir des exemples ci-dessus, mais Ahmad m'a le plus proche (merci). Pour ceux qui liront ceci à l'avenir, voici le code qui a fonctionné pour moi.
la source