Skip to content

Instantly share code, notes, and snippets.

@amontalenti
Last active December 24, 2015 12:44
Show Gist options
  • Select an option

  • Save amontalenti/7aa3950610b9f07afb63 to your computer and use it in GitHub Desktop.

Select an option

Save amontalenti/7aa3950610b9f07afb63 to your computer and use it in GitHub Desktop.
When using Python with concurrency, it can sometimes be helpful to delay the execution of functions. This utility function helps with that.
import functools
def delayed(fn):
"""Convert fn into delayed_fn with delayed(fn).
Take a function and convert it into a function that, rather than invoking
the function's call, instead returns a 3-tuple of `(fn, args, kwargs)`.
This can then be later called with the simple `fn(*args, **kwargs)` application
syntax, or the 3-tuple can be passed to other APIs that expect it, like
`concurrent.futures.ThreadPoolExecutor.submit(...)`.
Example:
>>> delayed_sum = delayed(sum)
>>> delayed_sum
<function sum at 0x1dec7e0>
>>> delayed_sum([1, 2, 3])
(<built-in function sum>, ([1, 2, 3],), {})
>>> fn, args, kwargs = delayed_sum([1, 2, 3])
>>> fn(*args, **kwargs)
6
This is useful for situations where you'd like to make code
look like it's doing a function invocation, but actually make
it do nothing more than save the function invocation for later.
It can eliminate the need for using nested functions, lambdas,
and callback wiring, and thus make your code more explicit.
The idea for this utility was taken from [joblib][1].
[1]: https://github.com/joblib/joblib/blob/5b7741b/joblib/parallel.py#L144
"""
def delayed_fn(*args, **kwargs):
return fn, args, kwargs
try:
delayed_fn = functools.wraps(fn)(delayed_fn)
except AttributeError:
# functools.wraps fails on some callable objects
pass
return delayed_fn
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment