What is a callback?

  • Its all about framework code that ‘call back’ into your code
  • Traditional code uses Hollywood principal, where “don’t call us, we’ll call you”
  • Callbacks are used for event-driven architectures (actual events, structuring of control flow)

Callback implementation

  • Give someone a callable
  • Someone may store it somewhere
  • container, attribute, whatever
  • or keep as local variable
  • Calls when appropriate
  • When it needs some specific functionality (for customization)
  • Or when appropriate events occur (state changes, user actions, etc)

Customization

  • Customizing sort (by key)

    • Read up on DSU pattern
    • Note that a little workaround is needed with the usual ‘call a method on each object’ OO idiom
def DSU_sort(mylist, key):
    aux = [(key(v), j, v) for j,v in enumerate(mylist)]
    aux.sort()
    mylist[:] = [v for k, j, v in aux]

OO Customizing: the TM DP

Template method design patter: perform the callbacks by self delegation:

class TMparent(object):
    self.somehook()

And customize by inheriting & overriding:

class TMchild(TMparent):
    pass

Customizing scheduling

  • Sched needs TWO callback functionalities:
  • What time is it right now?
  • Wait (sleep) until time T
  • The OO way (more structured):
   import time
   s=sched(time)

* the FP way (more flexible):
   s=sched(time.time,time.sleep)

* You might supply callbacks or not

* (Dependency Injections DP & variants)

Events

  • Events proper
  • Observer/observable design pattern
  • GUI frameworks (mouse, keyboard)
  • asynchornous (event-driven) I/O
  • System-event callbacks
  • Pseudo-events
  • parsing (SAX and other long tasks)
  • scheduled (sched)
  • concurrent (threads)
  • timing and debugging (timeit, pdb)

The Observer DP

  • Target object lets you add observers
  • could be simple callables or objects
  • when the target’s state changesm it calls back to the left observers know
  • Design choices:
  • General observers (callback on any state change)
  • Specific observers (callbacks on specific states)
  • grouped observers (objects with >1 methods for kinds of state-change)

GUI frameworks

  • Most classic of event-driven fields
  • consider Tkinter:
  • elementary callbacks for buttons
  • flexible, advanced callbacks and events (pressing the ‘a’ button)
  • can also bind by class, all, root window, etc

Callback issues

  • What arguments are to be used on the call?
  • No arguments: simplest, a bit rough
  • In observer: pass as argument the target object whose state just changed
  • Or: a ‘description of the state changes
  • Saves ‘round trips’ to obtain them
  • other: identifier or description of event
  • but? WHAT?!? check the PDF

Fixed args in callbacks

functools.partiabl(callable,*a,**kw)
    prebind any or all arguments
    x.setCbk(f,*a,**kw)

Callback dispatching

  • What if more than one callback is set for a single event (or, observable target)?
  • Remember and call the latest one only
  • simplest, roughest
  • Remember and call them all
  • LIFO? FIFO?
  • How do you remove a callback?
  • Can one callback ‘preempt’ others
  • Can events (or state changes) be grouped?
  • use object w/methods instead of callable

Callback and Errors

  • Are errors events like any others

  • Are they best singled-out?

  • Twisted Matrix’s deferred pattern: look this up! It holds:

    • N chained callbacks for successes +
    • M chained callbacks for errors
    • each callback is held with opt (*a, **kw)

System-events callbacks

  • For various Python system events:
   atexit.register(callable, *a, **k)
   oldhandler = signal.signal(signum, callable)
   sys.displayhook, sys.excepthook, sys.setttrace(callable)

* extension modules to that too:

 * readline.set_startup_hook
 * set_pre_input_ook
 * set_completer

Event-driven parsing

  • SAX for XML
  • sometimes very big!
  • events are start and end of tags
  • handlers are responsible for keeping stack or other structure as needed
  • often not necessary to keep all
  • XML DOM on other side

Scheduled callbacks

  • Standard library sched
s = sched.Sched
evt = s.enter(blah blah blah)
s.run() #runs events

Concurrent Callbacks

  • Useful for SR check
  • threading.Thread(blah)
  • stacklet.tasklet (stackless python)
  • processing.Process( like threading.Thread)
  • NWS sleigh: eachElem, eachWorker

Timing and Debugging

  • timeit.Timer(stmt, setup)
  • string arguments to compile and execute
  • dynamic language twist on callbacl
  • event for callback
  • setup: once before anything else
  • stmt: many times for running
  • pdb module
  • pdb.run and .runeval: strings
  • pdb.runcall: callable, arguments