2008-12-15 7 views
9

Dites que j'ai un paquet "mylibrary". Je veux que "mylibrary.config" soit disponible pour l'importation, soit en tant que module créé dynamiquement, soit en tant que module importé d'un endroit complètement différent qui serait alors "monté" dans l'espace de noms "mylibrary".Rendre un paquet virtuel disponible via sys.modules

Ie, je fais:

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

Étant donné que la configuration:

>>> import mylibrary.config # -> works 

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

Plus étrange encore:

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

Il semble donc que l'utilisation des œuvres à l'importation directe, les autres formes ne pas. Est-il possible de faire fonctionner ces travaux aussi?

Répondre

13

Vous devez singe-patch module non seulement dans sys.modules, mais aussi dans son module parent:

>>> 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

Vous pouvez essayer quelque chose comme ceci:

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

En plus ce qui suit:

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

Vous devez également faire:

import mylibrary 
mylibrary.config = config 
Questions connexes