Я пытаюсь понять схему цепочки ответственности, и в качестве упражнения я написал некоторый код. Этот код
class SomeObject:
def __init__(self):
self.integer_field = 0
self.float_field = 0.0
self.string_field = 'hi'
class EventGet:
def __init__(self, data_type):
self.data_type = data_type
class EventSet:
def __init__(self, value):
self.value = value
class NullHandler:
def __init__(self, successor=None):
self.__successor = successor
def handle(self, obj, event):
if self.__successor:
self.__successor.handle(obj, event)
class IntHandler(NullHandler):
def handle(self, obj, event):
if isinstance(event, EventGet) and event.data_type is int:
return obj.integer_field
elif isinstance(event, EventSet) and isinstance(event.value, int):
obj.integer_field = event.value
else:
super().handle(obj, event)
class FloatHandler(NullHandler):
def handle(self, obj, event):
if isinstance(event, EventGet) and event.data_type is float:
return obj.float_field
elif isinstance(event, EventSet) and isinstance(event.value, float):
obj.float_field = event.value
else:
super().handle(obj, event)
class StrHandler(NullHandler):
def handle(self, obj, event):
if isinstance(event, EventGet) and event.data_type is str:
return obj.string_field
elif isinstance(event, EventSet) and isinstance(event.value, str):
obj.string_field = event.value
else:
super().handle(obj, event)
Но это не работает, как я ожидаю. Вызывается следующим образом
obj = SomeObject()
chain = IntHandler(FloatHandler(StrHandler(NullHandler())))
print(chain.handle(obj, EventGet(int)))
print(chain.handle(obj, EventGet(float)))
print(chain.handle(obj, EventGet(str)))
chain.handle(obj, EventSet(1))
print(obj.integer_field)
chain.handle(obj, EventSet(1.1))
print(obj.float_field)
chain.handle(obj, EventSet('str'))
print(obj.string_field)
выдает сбивающий с толку вывод:
0 # That's ok
None # Why not 0.0?
None # Why not hi?
1 # That's ok
1.1 # That's ok
str # That's ok
Я не могу понять, почему при вызове chain.handle(obj, EventGet(float))
и chain.handle(obj, EventGet(str))
получается None
. В конце концов, в соответствующих позициях есть оператор return
(т.е. return obj.float_field
и return obj.string_field
).
Не могли бы вы объяснить мне, что не так в этом коде и как заставить его работать как положено? Большое спасибо заранее!