First, it seems proper to me to state that I've read over the following questions:
- Python imports by folder module
- Dynamic module import in Python
And, I don't feel like they address my use case. That said, here's my question:
How can I dynamically import from a configuration file like this:
[imports]
/var/imports/foo.py = baz monkey
/var/imports/bar.py = ape
So that I can call the known objects via RESTful interface like this.
# http://localhost/data?operation=get&class=baz&id=1
def handler(object):
def handle(self):
cls = instantiate(request.args["class"])
meth = request.args["operation"]
return getatt开发者_如何学Pythonr(cls,meth,request.args)
And it could respond with the result of get() on an instance of that class.
Look at the 2nd link again. It already mentions imp.load_source
:
import imp
# some sort of shared dict for everything imported
loaded = {}
def load(path, from_list):
# load the path
module = imp.load_source( "dummy", path)
for name in from_list:
# add the names
loaded[name] = getattr(module, name)
#lets say you have this:
data = "/var/imports/foo.py", ["baz"]
load(*data)
print loaded['baz'] # whatever foo.baz was
Now you can do something like this:
def instantiate( clsname ):
obj = loaded[clsname]
return obj()
I hope this gets you started.
Here's a rough sketch of a class registry you could use like this:
class ClassRegistry(object):
def __init__(self):
self.classes = {}
def add_file_classes(self, fname, class_list):
globals = {}
exec open(fname) in globals
for class_name in class_list:
self.classes[class_name] = getattr(globals, class_name)
def get_class(self, class_name):
return self.classes[class_name]
Read your config file and invoke add_file_classes
like this:
reg = ClassRegistry()
reg.add_file_classes("/var/imports/foo.py", ["baz", "monkey"])
reg.add_file_classes("/var/imports/bar.py", ["ape"])
then later:
cls = reg.get_class("baz")
Note that we aren't actually importing the files, simply executing them and collecting their results.
精彩评论