New submission from Josh Rosenberg:

Not sure if this is the right venue to propose this, but I'd like to propose 
adding a starcaller method to the standard library, either functools or 
operator (not sure if the proposal is more like partial or more like 
methodcaller).

Basically, right now, when you want to take an existing function and call it 
repeatedly with preconstructed tuples using functional tools (e.g. sorted or 
groupby's key argument, multiprocessing.Pool's various map-like methods), you 
need to either have a special starmethod (e.g. Pool.map vs. Pool.starmap), or 
if Python doesn't provide one, you need use Python-defined functions (and for 
stuff like Pool, you can't even use lambda due to pickling issues, so you need 
to define the utility somewhere else). This means that you can't reuse builtins 
for stuff like the old "find runs of consecutive numbers" example from the 
itertools docs ( https://docs.python.org/2.6/library/itertools.html#examples ).

In terms of behavior:

    starfunc = starcaller(func)

would be behave roughly the same as the following (less efficient) Python 2 
code:

    starfunc = functools.partial(apply, func)

(and perhaps starcaller(func, kwonly=True) would behave like 
functools.partial(apply, func, ()) to extend it to dicts).

This would make it possible to write the old consecutive numbers example:

    for k, g in groupby(enumerate(data), lambda (i,x):i-x):

(which is no longer legal since Py3 banned sequence unpacking in arguments like 
that) as:

    for k, g in groupby(enumerate(data), starcaller(operator.sub)):

It would also mean that instead of constantly needing to write new "star 
methods", you can just reuse existing functions with new batteries. For 
example, multiprocessing.Pool has a map and starmap function, but imap and 
imap_unordered have no starimap or starimap_unordered equivalents, which means 
using them at all requires you to def a function at trivial wrapper at global 
scope (possibly a long way away from the point of use) just to use an existing 
function ( def whydidineedthis(args): return existingfunction(*args) ).

With starcaller, there is no need to add starimap and friends, because the same 
result is easily achieved with:

    with multiprocessing.Pool() as pool:
        for res in pool.imap(starcaller(existingfunction), ...):

Is this a reasonable proposal? I could get an implementation ready fairly 
quickly, I'd just need to feedback on the name, which module it should be put 
in (functools or operator seem equally plausible) and whether the idea of using 
a keyword argument to the constructor makes more sense (kwonly=True) vs. 
expecting users to do functools.partial(starcaller(existingfunc), ()), vs. a 
separate class like doublestarcaller.

----------
components: Library (Lib)
messages: 278212
nosy: josh.r
priority: normal
severity: normal
status: open
title: Add a "starcaller" function
versions: Python 3.7

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue28381>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to