== Closures versus classes for capturing state Possibly like a lot of other people, I have a 'thread pool' Python module for doing decoupled [[asynchronous queries UsefulPythonThreads]] of things. The basic interface looks like this: > wp = WorkPool(HOWMANY) > for w in what: > wp.enqueue(wrap_up(w)) > wp.waitDone() > res = wp.getanswers() The important operation is _.enqueue(~~~~)_, which queues up __ to be called in a worker thread; its return value is saved, to be disgorged later by _.getanswers()_. To keep things simple, __ is called with no arguments. But usually what I really want to do is to call the same function with a bunch of different arguments, for example calling [[((is_in_sbl)) http://www.spamhaus.org/sbl/]] for a bunch of IP addresses. To make this work, I need to capture the argument (or arguments) and create a simple callable object that remembers them; in this example, that's done by ((wrap_up)). There's two ways of wrapping up this sort of state in Python: classes (okay, objects) and closures. In the class-based approach, ((wrap_up)) is actually a class; its ((__init__)) method saves _w_, and its ((__call__)) method uses the saved _w_ to do the actual function call. By contrast, in a closure-based approach ((wrap_up)) is a plain function that creates and returns closures, like this: > def wrap_up(w): > return lambda: real_func(w) The class approach is the more obvious and natural one, because the state saving is explicit. But when I wrote two structurally identical programs, the first one using a class and the second one with closures, I found that I plain liked closures better. For me, the drawback of the class based approach is that it's too verbose. The same ((wrap_up)) would be: > class wrap_up: > def __init__(self, w): > self.w = w > def __call__(self): > return real_func(self.w) (and it gets longer if you have more than one argument.) I have a visceral reaction to verbosity; in cases like this it feels like make-work. The retort is that closures are far more magic than classes for most people and it's better to avoid magic, even if the result is more verbose. For now, my view is that programming should be pleasant, not annoying, and that the verbosity of the class-based approach to state capture annoys me. So closures it is. (Perhaps the real answer is that WorkPool should have an ((.enqueue_call(func, *args, **kwargs))) method, as well as the plain _.enqueue()_ one. This strays towards the [[Humane Interfaces arguments OnInterfaceStyles]], though, so I'm a bit nervous.)