""" This file demonstrates using decorators not to modify a function but rather to send the function into a class which will use it later. This mirrors how works. The Flask handles listening for and parsing HTTP requests; it decides how to respond to those requests by checking the path and method against various decorator calls and calling the decorated function that matches. """ class Responder: """An example of the idea used by flask apps: decorator functions are left unmodified, and are also stored to be called under specific situations by the app.""" def __init__(self): self._exact = {} self._starts = {} self._contains = {} def startswith(self, prefix): def decorator(f): self._starts[prefix.lower()] = f return f return decorator def contains(self, substring): def decorator(f): self._contains[substring.lower()] = f return f return decorator def exact(self, string): def decorator(f): self._contains[string.lower()] = f return f return decorator def chat(self, message): m = message.strip().lower() for s,f in self._exact.items(): if m == s: return f(message) for s,f in self._starts.items(): if m.startswith(s): return f(message) for s,f in self._contains.items(): if s in m: return f(message) return 'Hmm...' res = Responder() @res.startswith('why') def f(s): return 'Why not?' @res.contains('?') def f(s): return 'I give up. '+s.strip() @res.exact('bye') def f(s): return 'Going so soon?' @res.contains('!') def f(s): raise StopIteration("I don't deal well with excitement. Goodbye.") print('Beginning conversation:', end='\n>>> ') import sys for line in sys.stdin: try: print(res.chat(line), end='\n>>> ') except StopIteration as ex: print(ex) break