途中,依存関係をあまり意識せずコードを書けるところまでしかできていない

用途

fixtureの生成など、実行順序に依存関係のあるコード。
(あと、走らせるとなかなか終わらない。)

	・解決したこと
		* 依存関係をあまり意識せずコードを書きたい。
	・未解決
		* 作業順序を変更したい
			+ model1,model2,...
			+ (model1.x model2.x,...),(model1.y model2.y,...)....
		* 作業を中断/再開したい
			* 中断したときにも、一揃いのデータが存在して欲しい
		* 進捗状況を把握したい

途中

code

import sys
from collections import defaultdict

class ActionQueue(object):
    def __init__(self):
        self.depends_dict = defaultdict(list)
        self.table = {} 
        self.finished = None
        self.result = None

    def depends(self, name):
        def _depends(fn):
            self.depends_dict[fn.__name__].append(name)
            return fn
        return _depends

    def add(self,fn):
        self.table[fn.__name__] = fn
        return fn

    def _eval(self,k, fn,*args):
        if k in self.finished:
            return 
        for dk in self.depends_dict.get(k,[]):
            dfn = self.table.get(dk)
            if dfn:
                self._eval(dk, dfn, *args)

        sys.stderr.write("\t%s.. \n" % k) 
        sys.stderr.flush()
        self.result[k] = fn(*args)
        self.finished[k] = True
        sys.stderr.write("\tdone\n")
        sys.stderr.flush()

    def _before_eval(self):
        self.finished = {}
        self.result = {}

    def eval_all(self, *args):
        self._before_eval()
        for k,v in self.table.items():
            self._eval(k,v,*args)
        return self.result

利用方法

## dependenty: f -> g -> {x,y,z} -> h

aq = ActionQueue()
add, depends = aq.add, aq.depends
import random

def _r(n):
    return random.randint(1, n)

def _i(x, i):
    return "%s:%d" % (x, i)

@add
def f():
    for i in xrange(_r(5)):
        print _i("f", i)
    
@add
@depends("f")
def g():
    for i in xrange(_r(5)):
        print _i("g", i)

@add
@depends("x")
@depends("y")
@depends("z")
def h():
    for i in xrange(_r(5)):
        print _i("h", i)

@add
@depends("g")
def x():
    for i in xrange(_r(5)):
        print _i("x", i)

@add
@depends("g")
def y():
    for i in xrange(_r(5)):
        print _i("y", i)

@add
@depends("g")
def z():
    for i in xrange(_r(5)):
        print _i("z", i)

####
aq.eval_all()

実行結果

	f.. 
f:0
f:1
	done
	g.. 
g:0
	done
	z.. 
z:0
z:1
z:2
z:3
z:4
	done
	y.. 
y:0
y:1
	done
	x.. 
x:0
x:1
x:2
x:3
x:4
	done
	h.. 
h:0
h:1
h:2
h:3
h:4
	done