2008-10-17 10 views

Antwort

52

den Python-docs auf __import__:

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

...

Wenn der Name variable Form package.module ist, in der Regel, die Top-Level-Paket (das Name bis der erste Punkt) zurückgegeben wird, nicht das Modul namentlich benannt. Wenn jedoch ein nicht leeres Ausgabeliste-Argument angegeben wird, wird das namentlich genannte Modul zurückgegeben. Dies ist für die Kompatibilität mit der Bytecode für die verschiedenen Arten von Import-Anweisung generiert; Bei der Verwendung von "import spam.ham.eggs" muss der Top-Level-Paket-Spam im importierenden Namespace platziert werden, aber wenn "von spam.ham importiert Eier" verwendet wird, muss das spam.ham-Unterpaket verwendet werden zu finden Sie die Eier variabel. Verwenden Sie als eine Abhilfe für dieses Verhalten getattr(), um die gewünschten Komponenten zu extrahieren. Zum Beispiel könnten Sie definieren die folgenden Helfer:

def my_import(name): 
    mod = __import__(name) 
    components = name.split('.') 
    for comp in components[1:]: 
     mod = getattr(mod, comp) 
    return mod 

paraphrasieren:

Wenn Sie fragen Sie nach somepackage.somemodule, __import__ kehrt somepackage.__init__.py, die oft leer.

Es wird somemodule zurück, wenn Sie fromlist (eine Liste der Variablennamen innerhalb somemodule Sie wollen, die nicht tatsächlich zurückgegeben werden) bieten

Sie kann auch, wie ich, die Funktion, die sie schlagen Gebrauch gemacht haben.

Hinweis: Ich habe diese Frage in vollem Umfang gestellt, um sie selbst zu beantworten. Es gab einen großen Bug in meinem Code, und nachdem ich ihn falsch diagnostiziert hatte, brauchte ich eine lange Zeit, um es herauszufinden, also dachte ich mir, ich würde der SO-Community helfen und den Fehler melden, dem ich hier begegnet bin.

7

Es gibt etwas, das funktioniert, wie Sie es wollen: 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'> 
+0

, die sehr nützlich ist, aber ich habe nicht wirklich eine andere Notwendigkeit in meinem Programm verdreht. Obwohl Sie als Gründer (!) Wahrscheinlich mehr über die Möglichkeiten Bescheid wissen als ich (habe sie nie benutzt). – dwestbrook

32

Python 2.7 importlib hat, gepunkteten Pfade als

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

Es gibt auch ein Python 2.6-Paket, das diese Funktionalität zurückführt. https://pypi.python.org/pypi/importlib/ – melinath

1

für Python 2.6 erwartet lösen, schrieb ich dieses Snippet:

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 
16

Es gibt eine einfachere Lösung, wie in der Dokumentation erklärt:

Wenn Sie einfach ein Modul (möglicherweise in einem Paket) nach Namen importieren möchten, können Sie __import __() aufrufen und es dann in sys nachschlagen.Module:

>>> import sys 
>>> name = 'foo.bar.baz' 
>>> __import__(name) 
<module 'foo' from ...> 
>>> baz = sys.modules[name] 
>>> baz 
<module 'foo.bar.baz' from ...> 
0

So wie ich ist

foo = __import__('foo', globals(), locals(), ["bar"], -1) 
foobar = eval("foo.bar") 

dann habe ich von allen Inhalten zugreifen können durch

foobar.functionName() 
+1

Warum nicht einfach, 'foo.bar' an diesem Punkt? –

Verwandte Themen