私は以下のように微調整されたバージョンを使用してデコレータについてもっと学ぼうとしています:ここから
def case(comparision):
def __assign_case(f):
f.__case = comparision
return f
return __assign_case
class switch:
def __init__(self):
self.__case_map = {}
def set_case(key,f):
self.__case_map[key] = f
a = [getattr(self,e) for e in dir(self) if getattr(self,e) is not None and hasattr(getattr(self,e),'__case')]
for f in a:
cases = getattr(f,'__case')
if isinstance(cases,tuple) or isinstance(cases,list):
for c in cases: set_case(c,f)
else:
set_case(cases,f)
print(self.__case_map)
def match(self,value):
try:
self.__case_map[value]
except KeyError:
return self.__case_map['_default']
return self.__case_map[value]
class b(switch):
@case((1,3))
def event_one(self):
print('Event handler for 1,3 in b')
@case(2)
def event_two(self):
print('Event handler for 2 in b')
@case('_default')
def default(self):
print('No match was found, using default case')
a = b()
a.match(1)()
a.match(2)()
a.match(5)()
の実行結果:
$ ./switch_decor.py
{1: <bound method b.event_one of <__main__.b object at 0x7f03374849d0>>, '_default': <bound method b.default of <__main__.b object at 0x7f03374849d0>>, 3: <bound method b.event_one of <__main__.b object at 0x7f03374849d0>>, 2: <bound method b.event_two of <__main__.b object at 0x7f03374849d0>>}
Event handler for 1,3 in b
Event handler for 2 in b
No match was found, using default case
いっぱいになった辞書に注目してください
私は自分のコードを封じ込めておくのが好きなので、次のようにcase
関数をswitch
クラスに移動しようとしていました。
class switch:
def __init__(self):
self.__case_map = {}
def set_case(key,f):
self.__case_map[key] = f
a = [getattr(self,e) for e in dir(self) if getattr(self,e) is not None and hasattr(getattr(self,e),'__case')]
for f in a:
cases = getattr(f,'__case')
if isinstance(cases,tuple) or isinstance(cases,list):
for c in cases: set_case(c,f)
else:
set_case(cases,f)
print(self.__case_map)
def match(self,value):
try:
self.__case_map[value]
except KeyError:
return self.__case_map['_default']
return self.__case_map[value]
@staticmethod
def case(comparision):
def __assign_case(f):
f.__case = comparision
return f
return __assign_case
class b(switch):
@switch.case((1,3))
def event_one(self):
print('Event handler for 1,3 in b')
@switch.case(2)
def event_two(self):
print('Event handler for 2 in b')
@switch.case('_default')
def default(self):
print('No match was found, using default case')
a = b()
a.match(1)()
a.match(2)()
a.match(5)()
しかし、私は空のself.__case_map
辞書を取得することになり、このエラーが発生します:
$ ./switch_decor_contained.py
{}
Traceback (most recent call last):
File "./switch_decor_contained.py", line 23, in match
self.__case_map[value]
KeyError: 1
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./switch_decor_contained.py", line 50, in <module>
a.match(1)()
File "./switch_decor_contained.py", line 25, in match
return self.__case_map['_default']
KeyError: '_default'
最初の空白の辞書に注意してください。で失敗します
a.match(1)
その前にreturn関数が呼び出され、2番目()
の関数は空白で例外をトリップする_default
関数ですが、返す関数値へのキーはありません。
上記の最初のコードセットでは、これをコンソールで実行すると次のようになります。
>>> hasattr(a.event_one, "__case")
True
しかし、上記の2番目のコードセットでは、
>>> hasattr(a.event_one, "__case")
False
@switch.case
その上でテストが示したように実行されているという事実にもかかわらず。クラス内で呼び出すと、いくつかの厄介な副作用があります。副作用は何ですか?
case
関数をswitch
クラスに移動し、それをメソッドとして使用して、クラス内の関数を正常に装飾するにはどうすればよいb
ですか?