importlib may be more appropriate as it uses / implements PEP302 .
Follow the example of DictImporter, but redefine find_moduleto find the real file name and save it in a dict, then redefine load_moduleto get the code from the found file.
You do not need to use sys.path once you have created your storage module
import imp
import os
import sys
import logging
logging.basicConfig(level=logging.DEBUG)
dprint = logging.debug
class MyImporter(object):
def __init__(self,path):
self.path=path
self.names = {}
def find_module(self,fullname,path=None):
dprint("find_module({fullname},{path})".format(**locals()))
ml = imp.find_module(fullname,path)
dprint(repr(ml))
raise ImportError
def load_module(self,fullname):
dprint("load_module({fullname})".format(**locals()))
return imp.load_module(fullname)
raise ImportError
def load_storage( path, modname=None ):
if modname is None:
modname = os.path.basename(path)
mod = imp.new_module(modname)
sys.modules[modname] = mod
assert mod.__name__== modname
mod.__path__=[path]
mod.__loader__= MyImporter(path)
return mod
if __name__=="__main__":
load_storage("arbitrary-path-to-code/Storage")
from Storage import plain
from Storage import mypkg
Then when you import Storage.mypackage, python will immediately use your importer without bothering to searchsys.path
. "", , Storage sys.path, 3.1, 2.6, , loader, PEP302.
sys.meta_path, 3.1 StackOverflow 2.6 ImportError. ... , .