2008-12-15 14 views
9

Digamos que tengo un paquete "mylibrary".Haciendo un paquete virtual disponible a través de sys.modules

Quiero que "mylibrary.config" esté disponible para importar, ya sea como un módulo creado dinámicamente, o como un módulo importado de un lugar completamente diferente que básicamente se "montará" dentro del espacio de nombres "mylibrary".

Es decir, que hago:

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

Teniendo en cuenta que la configuración:

>>> import mylibrary.config # -> works 

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

Aún más extraño:

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

Así que parece que los usuarios de las obras directos de importación, las otras formas no haga. ¿Es posible hacer esos trabajos también?

Respuesta

13

Necesitas mono-parche el módulo no sólo en sys.modules, sino también en su módulo padre:

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

Usted puede intentar algo como esto:

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

Así como lo siguiente:

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

también hay que hacer:

import mylibrary 
mylibrary.config = config 
Cuestiones relacionadas