python - from - Hacer un paquete virtual disponible a través de sys.modules
python relative import (3)
Digamos que tengo un paquete "mylibrary".
Quiero hacer que "mylibrary.config" esté disponible para la importación, ya sea como un módulo creado dinámicamente, o como un módulo importado de un lugar completamente diferente que básicamente sería "montado" dentro del espacio de nombres "mylibrary".
Es decir, lo hago:
import sys, types
sys.modules[''mylibrary.config''] = types.ModuleType(''config'')
Teniendo en cuenta esa configuración:
>>> import mylibrary.config # -> works
>>> from mylibrary import config
<type ''exceptions.ImportError''>: cannot import name config
Incluso más extraño:
>>> import mylibrary.config as X
<type ''exceptions.ImportError''>: cannot import name config
Entonces parece que usar los trabajos de importación directa, las otras formas no. ¿Es posible hacer esos trabajos también?
Necesitará parchear el módulo no solo en sys.modules, sino también en su módulo principal:
>>> 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)>
Puedes probar 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
Además de lo siguiente:
import sys, types
config = types.ModuleType(''config'')
sys.modules[''mylibrary.config''] = config
También debes hacer:
import mylibrary
mylibrary.config = config