正在加载...

从GAE Datastore导入python module的可行方案

November 16th, 2010

Micolog支持插件机制已经有一段时间了,但是,每次添加删除插件都需要在客户端使用Google Launcher重新上传整个micolog,感觉不是很方便。为了解决这个问题,准备在下一个版本中实现插件的动态加载,更新和删除。

当前,可能的方案之一,就是将插件实现的代码(py文件)和资源(Html,图片等)都使用GAE Datastore来存储。

于是,今天试验了一下,初步验证了,该方案的可行性。

这个方案的关键点在于python module的动态加载。

查阅了一下资料,根据官方文档显示,我们可以自定义模块导入的方法,其中使用的技术叫做 Import Hooks (http://www.python.org/dev/peps/pep-0302/).

为此我们必须创建一个类,实现 find_module 和 load_module方法,然后将这个类加入到sys.path_hooks

以下是实现代码(实现了将文本导入为模块的功能)

 

#-------------------------------------------------------------------------------
# Name:        gaedbimporter
# Purpose:
#
# Author:      Xuming
#
# Created:     16-11-2010
#-------------------------------------------------------------------------------
#!/usr/bin/env python

import sys,  marshal, imp, new
class gaedbimporter(object):
	def __init__(self, item, *args, **kw):
		if item != "gaedb":
			raise ImportError

	def is_package(self,fullname):
		return True

	def get_code(self,fullname):
		return  compile(self.get_source(fullname), "db:%s" % fullname, "exec")

	def get_source(self,fullname):
		return '''def test():
		    		print 'test' '''

	def find_module(self, fullname, path=None):
		if fullname=='dbtest':
			return self
		else:
			return None

	def load_module(self, fullname):
		print "load_module:", fullname
		ispkg=True
		code=self.get_code(fullname)

		#ispkg, code = self._get_code(fullname)
		mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
		mod.__file__ = "<%s>" % self.__class__.__name__
		mod.__loader__ = self
		if ispkg:
			mod.__path__ = []
		#print mod.__dict__
		exec code in mod.__dict__
		return mod

	@classmethod
	def install(cls):
		sys.path_hooks.append(gaedbimporter)
		sys.path_importer_cache.clear() # probably not necessary
		sys.path.insert(0, "gaedb")

if __name__ == "__main__":
	gaedbimporter.install()
	from dbtest import *
	test()

 

更进一步,我们可以将模块编译后存储在GAE DataStore中,来提高加载的速度。以上只是验证代码,但通过一些附加的代码,相信很容易就可以实现Python Module的动态加载功能了。

 

相关阅读:



google reader 抓虾
bloglines my yahoo
哪吒 鲜果
* 更多订阅本站方式请看 订阅帮助