[Twisted-Python] addCallback0 convenience method
Drew Smathers
drew.smathers at gmail.com
Mon May 4 09:59:07 MDT 2009
On Mon, May 4, 2009 at 6:26 AM, Terry Jones <terry at jon.es> wrote:
> There are two minor niggles I frequently run into when writing code with
> deferreds and callbacks:
>
> 1. I very often write callbacks that ignore the incoming result: I tend to
> write this as def cb(_): ...
>
> 2. I sometimes write functions that I want to call both from within a
> callback chain and when not in a callback chain. Usually this is
> another case of writing def x(_, arg1, arg2) etc. and documenting that
> the extra unused arg is for when the function is called as part of a
> callback chain. This looks odder when the function is some kind of
> utility living in different Python source file, and is thus distant
> from its use in a callback chain.
>
> Seeing as n-1 of the add* methods of t.i.defer.Deferred are convenience
> methods for calling addCallbacks, I propose another:
>
> def addCallback0(self, callback, *args, **kw):
> self.addCallback(lambda result: callback(*args, **kw))
>
> This allows you to write callback functions that will not be passed the
> result of the callback chain. That means I never have to deal with 1 and 2
> above. They're minor niggles, of course, but they make code look less
> attractive and a little harder to understand. Yes, I could write my own
> standalone function
>
> def addCallback0(d, callback, *args, **kw):
> d.addCallback(lambda result: callback(*args, **kw))
>
> and pass it my deferreds. And yes, I can also write my own wrapper to call
> other methods which don't take a callback result as their first argument.
>
> But all this would be nicer if addCallback0 was part of the Deferred class.
> I don't think we need a corresponding addBoth0 or addErrback0 etc., though.
>
> Terry
>
I vote instead to add a new function impartial() to standard library
functools module:
d.addCallback(impartial(callback))
Kidding, of source. Seriously, though, I think the regular way of
attaching "lambda ign: cb(*a, **kw)" is concise enough to warrant not
adding more to the Deferred API. A more general solution might be to
wrap functions - something like the inverse of functools.partial():
def shiftargs(level=1)
def decorator(f)
@wraps(f)
def _wrapper(*a, **kw):
return f(a[level:], **kw)
return _wrapper
return decorator
Still - just my opinion, of course - having such a function (either
callback0 or shiftargs) feels too esoteric, and the intent is less
explicit than the lambda statement.
-Drew
More information about the Twisted-Python
mailing list