我一直在尝试使用以下调整后的版本了解有关装饰器的更多信息:here
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)
在调用返回函数之前,第二()
个函数是字典空白触发异常的函数,但没有_default
返回函数值的键。
在上面的第一组代码中,在控制台中运行它会给出:
>>> hasattr(a.event_one, "__case")
True
但是在上面的第二组代码中,运行
>>> hasattr(a.event_one, "__case")
False
尽管事实证明@switch.case
正在运行测试。在类中调用它会产生一些不利的副作用。有什么副作用?
如何将case
函数移动到switch
类中并成功地将其用作装饰类中的函数的方法b
?