2008-12-15 6 views
9

Angenommen, ich habe ein Paket "mylibrary".Ein virtuelles Paket über sys.modules verfügbar machen

Ich möchte "mylibrary.config" für den Import zur Verfügung stellen, entweder als dynamisch erzeugtes Modul oder als ein Modul, das von einem völlig anderen Ort importiert wurde, der dann im Namespace "mylibrary" "mounted" würde.

Das heißt, ich mache:

import sys, types 
sys.modules['mylibrary.config'] = types.ModuleType('config') 

Da Setup:

>>> import mylibrary.config # -> works 

>>> from mylibrary import config 
<type 'exceptions.ImportError'>: cannot import name config 

Noch seltsamer:

>>> import mylibrary.config as X 
<type 'exceptions.ImportError'>: cannot import name config 

So scheint es, dass die direkten Import Werke verwenden, die anderen Formen unterlassen Sie. Ist es möglich, dass diese auch funktionieren?

Antwort

13

Sie müssen Affen-Patch das Modul nicht nur in sys.modules, sondern auch in seinem übergeordneten Modul:

>>> import sys,types,xml 
>>> xml.config = sys.modules['xml.config'] = types.ModuleType('xml.config') 
>>> import xml.config 
>>> from xml import config 
>>> from xml import config as x 
>>> x 
<module 'xml.config' (built-in)> 
1

Sie so etwas wie dies versuchen:

class VirtualModule(object): 
    def __init__(self, modname, subModules): 
    try: 
     import sys 
     self._mod = __import__(modname) 
     sys.modules[modname] = self 
     __import__(modname) 
     self._modname = modname 
     self._subModules = subModules 
    except ImportError, err: 
     pass # please signal error in some useful way :-) 
    def __repr__(self): 
    return "Virtual module for " + self._modname 
    def __getattr__(self, attrname): 
    if attrname in self._subModules.keys(): 
     import sys 
     __import__(self._subModules[attrname]) 
     return sys.modules[self._subModules[attrname]] 
    else: 
     return self._mod.__dict__[attrname] 


VirtualModule('mylibrary', {'config': 'actual_module_for_config'}) 

import mylibrary 
mylibrary.config 
mylibrary.some_function 
1

Neben folgendes:

import sys, types 
config = types.ModuleType('config') 
sys.modules['mylibrary.config'] = config 

Sie müssen auch tun:

import mylibrary 
mylibrary.config = config