コード

ちっちゃい! コメントのほうが多い!


# -*- coding: utf8 -*-
"kwmatch.py PUBLIC DOMAIN"
class KwMatch(object):
#引数の型によって比較関数切り替え
cmps={
type:lambda x,y:isinstance(x,y),
slice:lambda x,y:y.start<=x<=y.stop,
set:lambda x,y:x in y,
}
def __init__(self):
self.cases=[] # (case,fnc) のペアが caseデコレータ適用順に格納される
self.cmps=KwMatch.cmps.copy()
self.cmp_default=lambda x,y:x==y
def _defaultfnc(self,*args,**kwargs):
raise Exception
def case(self,**kwargs): # caseデコレータ 適用の順番が重要
def _(f):
self.cases.append((kwargs,f))
return f
return _
def default(self,f): # デコレータ
self._defaultfnc=f
# cmpを差し替えれば、引数同士の大小関係などもチェック可能
#分岐条件の境界テストなども、関数の中身に触れないで 条件だけチェックできる
def cmp(self,kwargs,case):
return all( [self.cmps.get(type(v),self.cmp_default)
(kwargs[k],v)
for k,v in case.items()])
def __call__(self,*args,**kwargs):
#argsでkwargsを更新するには、先に g の引数、引数名を決定する必要あり
#ニワトリとタマゴ
for c,f in self.cases: #中身はif文をループで回してる。
if self.cmp(kwargs,c):
g=f
break
else:
g=self._defaultfnc
return g(*args,**kwargs)