43 votes

__Import__ de Python ne fonctionne pas comme prévu

Lorsque vous utilisez __import__ avec un nom en pointillé, comme par exemple: somepackage.somemodule , le module renvoyé n'est pas somemodule , tout ce qui est renvoyé semble être en grande partie vide! que se passe t-il ici?

54voto

dwestbrook Points 1754

À partir du python docs sur __import__:

__import__( name[, globals[, locals[, fromlist[, level]]]])

...

Lorsque le nom de la variable est de la forme package.module, normalement, l' package de niveau supérieur (le nom jusqu'à le premier point) est retournée, et non pas le module nommé par son nom. Toutefois, lorsqu'un non-vide fromlist argument est donné, le module appelé par son nom est retourné. Ceci est fait pour assurer la compatibilité avec le bytecode généré pour l' différents types d'instruction d'importation; lors de l'utilisation de "l'importation de spam.le jambon.les œufs", le package de niveau supérieur spam doit être placé dans l espace de noms, mais quand à l'aide de "contre le spam.jambon importer des œufs", le le spam.ham sous-paquetage doit être utilisé pour trouver les œufs variable. En tant que solution de contournement pour ce problème, utilisez l' getattr() pour extraire les des composants. Par exemple, vous pourriez définir l'assistance 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 sera de retour somemodule si vous fournissez fromlist (une liste des noms de variable à l'intérieur d' somemodule vous voulez, qui ne sont en fait pas retourné)

Vous pouvez aussi, comme je l'ai fait, l'utilisation de la fonction qu'ils suggèrent.

Note: j'ai posé cette question avec l'intention de répondre moi-même. Il y a un gros bug dans mon code, et d'avoir mal diagnostiquée, il m'a fallu du temps pour le comprendre, alors j'ai pensé aider à la soi une communauté et après la chasse aux sorcières que j'ai rencontré ici.

32voto

cerberos Points 2000

python 2.7 a importlib, les chemins en pointillés résolus comme prévu

 import importlib
foo = importlib.import_module('a.dotted.path')
instance = foo.SomeClass()
 

16voto

Paolo Points 151

Il existe une solution plus simple, comme expliqué dans la documentation:

Si vous souhaitez simplement importer un module (éventuellement 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 ...>
 

7voto

Glyph Points 17756

Il y a quelque chose qui fonctionne comme vous le souhaitez: 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'>
 

1voto

David Seddon Points 11

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
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X