Am 06.01.2014 16:59, schrieb Guido van Rossum:
This API is more or less constrained (== copied from) the same API in
concurrent.futures and I don't think it is a big deal to have to work

Sure, but why work around N times (at each and every place in user code) if it could be fixed in one place?

around it. (The Tulip philosophy is roughly "if you find yourself
adding callbacks to futures, you're either writing a framework or

So user code should be coroutine/sequential-style _only_? Mmh.

doing it wrong" :-)

In this example, I am not writing a framework, so I guess I must be doing it wrong;)

Is this the preferred idiom for doing it right?


def get_and_print_sales(product):
   sales = yield from session.call("com.myapp.sales_by_product", product)
   print("Sales {}: {}".format(product, sales))

tasks = []
for product in ["product2", "product3", "product5"]:
   tasks.append(asyncio.Task(get_and_print_sales(product)))
yield from asyncio.wait(tasks)



I usually prefer lambdas for this kind of adaptation, but in your
example (where the callback is added in a loop and one of the
parameters varies over the loop) you actually have to use
functools.partial() to avoid the late binding of that variable.

The currying version would look like this:


import functools

def print_sales(product, future):
   sales = future.result()
   print("Sales {}: {}".format(product, sales))

fl = []
for product in ["product2", "product3", "product5"]:
   f = session.call("com.myapp.sales_by_product", product)
   f.add_done_callback(functools.partial(print_sales, product))
   fl.append(f)
yield from asyncio.gather(*fl)


Quite verbose.

FWIW, I don't understand why currying via functools.partial would be superior to adding args/kwargs forwarding to add_done_callback ..

Both are "superior" to doing the obvious and dirty

future.args = [product]

though, since that doesnt't cut it for multiple callbacks with different args being added to the future.

/Tobias


On Mon, Jan 6, 2014 at 3:42 AM, Tobias Oberstein
<[email protected]> wrote:
Am 06.01.2014 14:31, schrieb Victor Stinner:

You can use partial.functools(), example:

def f(*args, **kw): print(args, kw)

...

import functools
g = functools.partial(f, 1, 2, 3, key='value')

g()

((1, 2, 3), {'key': 'value'})

Victor


Sure, that works. But while currying might be intellectually exciting, it
makes the code even more verbose.

And it might negatively effect performance .. it'll produce lots of short
lived functions under the hood, or not?

/Tobias




Reply via email to