Lorsque vous utilisez __import__
avec un nom en pointillé, quelque chose comme: somepackage.somemodule
, le module retourné n'est pas somemodule
, tout ce qui est retourné semble être presque vide! que se passe t-il ici?__import__ Python ne fonctionne pas comme prévu
Répondre
De la documentation python sur __import__
:
__import__(name[, globals[, locals[, fromlist[, level]]]])
...
Lorsque la variable nom est de la forme package.module, normalement, le paquet de haut niveau (la nom jusqu'à le premier point) est renvoyé, pas le module nommé par son nom. Cependant, lorsqu'un argument non vide de liste est donné, le module nommé par son nom est renvoyé. Cela est fait pour la compatibilité avec le bytecode généré pour les différents types de déclaration d'importation; ; lors de l'utilisation de "import spam.ham.eggs", le spam de niveau supérieur doit être placé dans l'espace de noms d'importation, mais lorsque utilise "from spam.ham import eggs", le sous-paquetage spam.ham doit être utilisé à trouver les oeufs variable. Pour résoudre ce problème, utilisez getattr() pour extraire les composants souhaités. Par exemple, vous pouvez définir l'aide suivante:
def my_import(name): mod = __import__(name) components = name.split('.') for comp in components[1:]: mod = getattr(mod, comp) return mod
Pour paraphraser:
Lorsque vous demandez somepackage.somemodule
, __import__
retours somepackage.__init__.py
, ce qui est souvent vide.
Il retournera somemodule
si vous fournissez fromlist
(une liste des noms de variables à l'intérieur somemodule
que vous voulez, qui ne sont pas réellement retournés)
Vous pouvez aussi, comme je l'ai fait, utilisez la fonction qu'ils suggèrent.
Note: J'ai posé cette question dans l'intention d'y répondre moi-même. Il y avait un gros bug dans mon code, et après l'avoir mal diagnostiqué, il m'a fallu beaucoup de temps pour le comprendre, donc j'ai pensé que j'aiderais la communauté SO et posterais le gotcha que j'ai rencontré ici.
Il y a quelque chose qui fonctionne comme vous voulez à: twisted.python.reflect.namedAny
:
>>> from twisted.python.reflect import namedAny
>>> namedAny("operator.eq")
<built-in function eq>
>>> namedAny("pysqlite2.dbapi2.connect")
<built-in function connect>
>>> namedAny("os")
<module 'os' from '/usr/lib/python2.5/os.pyc'>
Python 2.7 a importlib, chemins pointillées résoudre comme prévu
import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
Il y a aussi un paquet python 2.6 qui supporte cette fonctionnalité. https://pypi.python.org/pypi/importlib/ – melinath
Pour python 2.6, j'ai écrit cet extrait:
def import_and_get_mod(str, parent_mod=None):
"""Attempts to import the supplied string as a module.
Returns the module that was imported."""
mods = str.split('.')
child_mod_str = '.'.join(mods[1:])
if parent_mod is None:
if len(mods) > 1:
#First time this function is called; import the module
#__import__() will only return the top level module
return import_and_get_mod(child_mod_str, __import__(str))
else:
return __import__(str)
else:
mod = getattr(parent_mod, mods[0])
if len(mods) > 1:
#We're not yet at the intended module; drill down
return import_and_get_mod(child_mod_str, mod)
else:
return mod
Il existe une solution plus simple, comme expliqué dans la documentation:
Si vous souhaitez simplement importer un module (potentiellement dans un package) par son nom, vous pouvez appeler __import __(), puis le rechercher dans sys.modules:
>>> import sys
>>> name = 'foo.bar.baz'
>>> __import__(name)
<module 'foo' from ...>
>>> baz = sys.modules[name]
>>> baz
<module 'foo.bar.baz' from ...>
La façon dont je l'ai fait est
foo = __import__('foo', globals(), locals(), ["bar"], -1)
foobar = eval("foo.bar")
alors je peux accéder à tout contenu par
foobar.functionName()
Pourquoi pas juste, 'foo.bar' à ce moment-là? –
- 1. Python .sort() ne fonctionne pas comme prévu
- 2. str.startswith() ne fonctionne pas comme prévu
- 3. Javascript ne fonctionne pas comme prévu, pourquoi?
- 4. J @ ne fonctionne pas comme prévu
- 5. "LIKE" ne fonctionne pas comme prévu
- 6. addEventListener & wmp ne fonctionne pas comme prévu
- 7. Regroupement Django ne fonctionne pas comme prévu
- 8. comparer deux chaînes avec 'est' - ne fonctionne pas comme prévu
- 9. La redirection d'assemblage ne fonctionne pas comme prévu
- 10. L'automatisation de Word Mailmerge ne fonctionne pas comme prévu
- 11. exec() ne fonctionne pas comme prévu dans PHP
- 12. prototype: Element.remove.bind (foo) ne fonctionne pas comme prévu
- 13. RegEx en Java ne fonctionne pas comme prévu
- 14. str.startswith() ne fonctionne pas comme je l'ai prévu
- 15. git --git-dir ne fonctionne pas comme prévu
- 16. Boost regex ne fonctionne pas comme prévu dans mon code
- 17. Silverlight checkbox la liaison bidirectionnelle ne fonctionne pas comme prévu
- 18. ASP.NET MVC FileStreamResult ne fonctionne pas comme prévu
- 19. middleware de connexion django ne fonctionne pas comme prévu
- 20. Le compteur global dans c ne fonctionne pas comme prévu
- 21. La balise JUnit attendue ne fonctionne pas comme prévu
- 22. variables globales dans php ne fonctionne pas comme prévu
- 23. Crypter en PHP ne fonctionne pas comme prévu
- 24. La transaction SQLite ne fonctionne pas comme prévu
- 25. La propriété StackPanel.Visibility ne fonctionne pas comme prévu?
- 26. Pourquoi Read() ne fonctionne-t-il pas comme prévu?
- 27. Type.IsSubclassOf ne se comporte pas comme prévu
- 28. PostSharp OnExceptionAspect ne fonctionnait pas comme prévu
- 29. Comme dans l'instruction CASE ne pas évaluer comme prévu
- 30. problème avec python et __import__
C'est très utile, mais je n'ai pas vraiment tout autre besoin de tordu dans mon programme. Bien que, en tant que fondateur (!), Vous êtes probablement plus au courant des possibilités que moi (jamais utilisé). – dwestbrook