0% found this document useful (0 votes)
62 views

Don't Call Us, We'll Call You:: Callback Patterns and Idioms in Python

Python
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
62 views

Don't Call Us, We'll Call You:: Callback Patterns and Idioms in Python

Python
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 18

Don't call us, we'll call you:

callback patterns and idioms in Python


http://www.aleax.it/pyc08_cback.pdf

2008 Google -- [email protected]


Sunday, March 9, 2008

Audience levels for this talk


Shu
("Retain")

Ha
("Detach")

Ri
("Transcend")
Sunday, March 9, 2008

2
2

The "Callback" concept


it's all about library/framework code that
"calls back" into YOUR code
rather than the "traditional" (procedural)
approach where YOU call code supplied as
entry points by libraries &c
"the Hollywood principle": "don't call us,
we'll call you"
coinage: Richard E. Sweet, in "The Mesa Programming
Environment", SigPLAN Notices, July 1985

for: customization (flexibility) and "event-driven"


architectures ("lightweight concurrency")
3
Sunday, March 9, 2008

"Callback" implementation
give "somebody" a callable
the "somebody" may store it "somewhere"
a container, an attribute, whatever
or even just keep it as a local variable
and calls it "when appropriate"
when it needs some specific functionality
(i.e., for customization)
or, when appropriate events occur (state
changes, user actions, network or other
I/O, timeouts, system events, ...)
4
Sunday, March 9, 2008

Customization

5
Sunday, March 9, 2008

Customizing sort (by key)


mylist.sort(key=str.toupper)

handily, speedily embodies the DSU pattern:


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]

Note that a little "workaround" is needed wrt the


usual "call a method on each object" OO idiom...

6
Sunday, March 9, 2008

OO customizing: the TM DP
"Template Method" Design Pattern: perform
the callbacks by "self delegation":
class TMparent(object):
...self.somehook()...

and customize by inheriting & overriding:


class TMchild(TMparent):
...def somehook(self):...

handy, compact, sometimes a bit rigid


http://video.google.com/videoplay?
docid=-5434189201555650834 and http://
www.aleax.it/goo_pydp.pdf (49ff) for more
7
Sunday, March 9, 2008

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 default callbacks, or not


(Dependency Injection DP & variants)
8
Sunday, March 9, 2008

Events

9
Sunday, March 9, 2008

Kinds of "Event" callbacks


the Observer/Observable design pattern
GUI frameworks (mouse, keyboard, ...)
asynchronous (event-driven) I/O (net &c)
"event-driven" parsing (SAX &c)
"scheduled" callbacks (sched)
"concurrent" callbacks (threads &c)
timing and debugging (timeit, pdb, ...)
"system-event" callbacks

10
Sunday, March 9, 2008

10

The Observer DP
a "target object" lets you add "observers"
could be simple callables, or objects
when the target's state changes, it calls
back to "let the observers know"
design choices: "general" observers
(callbacks on ANY state change), "specific"
observers (callbacks on SPECIFIC state
changes; level of specificity may vary),
"grouped" observers (objects with >1
methods for kinds of state-change), ...

11
Sunday, March 9, 2008

11

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
lets 1 callable observe several targets
or: a "description" of the state changes
saves "round-trips" to obtain them
other: identifier or description of event
but -- what about other arguments (related
to the callable, not to the target/event)...?
12
Sunday, March 9, 2008

12

Fixed args in callbacks


functools.partial(callable, *a, **kw)
pre-bind any or all arguments
however, note the difference...:
x.setCbk(functools.partial(f, *a, **kw))
vs
x.setCbk(f, *a, **kw)
...having the set-callback itself accept (and
pre-bind) arguments is far neater/handier
sombunall1 Python callback systems do that
1:

Robert Anton Wilson

Sunday, March 9, 2008

13
13

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? or...?
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
14
Sunday, March 9, 2008

14

Callbacks and Errors


are "errors" events like any others?
or are they best singled-out?

http://www.python.org/pycon/papers/deferex/

Twisted Matrix's "Deferred" pattern: one


Deferred object holds...
N "chained" callbacks for "successes" +
M "chained" callbacks for "errors"
each callback is held WITH opt *a, **kw
plus, argument for "event / error
identification" (or, result of previous
callback along the appropriate "chain")
15
Sunday, March 9, 2008

15

Scheduled callbacks
standard library module sched
s = sched.Sched(timefunc, delayfunc)
e.g, Sched(time.time, time.sleep)
evt = s.enter(delay, priority, callable, arg)
or s.enterabs(time, priority, callable, arg)
may s.cancel(evt) later
s.run() runs events until queue is empty (or
an exception is raised in callable or
delayfunc: it propagates but leaves s in
stable state, s.run can be called again later)
16
Sunday, March 9, 2008

16

System-events callbacks
for system-events:
atexit.register(callable, *a, **k)
oldhandler = signal.signal(signum, callable)
sys.displayhook, sys.excepthook,
sys.settrace(callable)
readline.set_startup_hook,
set_pre_input_hook, set_completer

17
Sunday, March 9, 2008

17

Q&A
http://www.aleax.it/pyc08_cback.pdf

!
18

Sunday, March 9, 2008

18

You might also like