2010-09-14

関数呼び出しをタプル形式にして遅延させる関数

関数呼び出しをタプルの情報にして保存するしくみを作った。
これを使えばWEBアプリでリクエストをまたいで関数呼び出しを遅延させることができるようになります。
関数呼び出しをタプル形式にして、memcacheなどに保存しておき、次に来たときに本当に呼び出したり。

# coding: utf-8
import inspect
import imp

def freeze_func(func, *args, **kwargs):
u"""
関数呼び出しを保存可能なタプル形式に変換する。
"""
m = inspect.getmodule(func)
return m.__name__, func.__name__, args, kwargs

def __importer(m, path):
a = imp.find_module(m[0], path)
b = imp.load_module(m[0], *a)
if len(m) > 1:
return __importer(m[1:], b.__path__)
else:
return b

def _importer(modname):
modname = modname.split(".")
return __importer(modname, None)



def unfreeze_func(info):
u"""
タプル形式で保存された関数呼び出しを関数に復元して実行する。
"""
b = _importer(info[0])
f = getattr(b, info[1])
args = info[2]
kwargs = info[3]
return f(*args, **kwargs)

if __name__ == "__main__":
import re
info = freeze_func(re.sub, r"[A-Za-z]", "*", "5-3-1 Asakusabashi")
print info # -> ('re', 'sub', ('[A-Za-z]', '*', '5-3-1 Asakusabashi'), {})
print unfreeze_func(info) # -> "5-3-1 ************"