2008-12-15 9 views
9

Powiedz, że mam pakiet "mylibrary".Udostępnianie pakietu wirtualnego za pośrednictwem sys.modules

Chcę, aby plik "mylibrary.config" był dostępny do importowania, albo jako dynamicznie tworzony moduł, albo moduł importowany z zupełnie innego miejsca, które następnie byłoby zasadniczo "montowane" w przestrzeni nazw "mylibrary".

Ie, robię:

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

Zważywszy, że konfiguracja:

>>> import mylibrary.config # -> works 

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

Nawet obcy:

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

Wydaje się więc, że za pomocą bezpośrednich prac na przywóz, innych form nie rób. Czy możliwe jest również wykonanie tych prac?

Odpowiedz

13

Trzeba monkey-plaster modułu nie tylko w sys.modules, ale również w jego modułu nadrzędnego:

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

Można spróbować czegoś takiego:

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

Jak również co następuje:

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

też trzeba zrobić:

import mylibrary 
mylibrary.config = config