This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Operators in operator module don't work with keyword arguments
Type: enhancement Stage:
Components: Library (Lib) Versions:
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: rhettinger Nosy List: leonidas, rhettinger
Priority: normal Keywords:

Created on 2009-03-26 15:48 by leonidas, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (4)
msg84181 - (view) Author: Marek Kubica (leonidas) Date: 2009-03-26 15:48
When calling operators from the ``operator``-module, they refuse to
accept keyword arguments:

operator.add(a=1, b=2)
TypeError: add() takes no keyword arguments

Operators with keyword arguments are important when one wants to create
partial functions with non-positional arguments.

Take for example ``operator.mod`` where the order of the arguments matters:

This works:
map(lambda x: x % 2, range(5))

This does not work, since ``operator.mod`` does not support keyword
arguments:
map(functools.partial(operator.mod, b=2), range(5))

So there are two solutions: define one's own add(), mod(), contains()
etc. but then the ``operator`` module is rather useless or make them
accept keyword arguments. With ``partial`` in the Stdlib this solution
would be a whole lot nicer.
msg84189 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-03-26 17:27
Sounds like what you're really looking for is a version of partial()
that lets you bind positional arguments in any position.  Something
like:  partial(operator.mod, (1,2)) that pre-binds 2 to argument
position 1.  

Changing the language to match the existing partial() function instead
of changing partial() to fit the language seems like "the tail wagging
the dog".

FWIW, I don't think partial actually buys you anything useful.  It's
implementation isn't as flexible as a lambda, nor is it any faster.  I
think it mainly serves those who have an aversion to lambda, perhaps
because of its name.

Also, I don't think it's a good idea to assign arbitrary keywords to the
operator functions unless those keywords have some meaning that makes
programs more readable.  The names "a" and "b" are only mildly useful a
position placeholders.  Names like "divisor" and "dividend" are more
descriptive, but that is overkill.

Overall, am -1 on the proposal.
msg84192 - (view) Author: Marek Kubica (leonidas) Date: 2009-03-26 17:41
Well, some Schemes have an CURRYR variant which creates partial
functions with positional arguments from the right but the current
solution with partial accepting keywords is way more flexible since I
can pre-set any arguments I like in such a function in any order. Doing
so by using keyword arguments looks cleaner than by using the position
of the argument.

Compare ``partial(operator.mod, (2, 2))`` with ``partial(operator.mod,
divisor=2)`` and at least to me, it is clearer what is happening in the
second case. Even ``partial(operator.mod, b=2)`` looks simpler, albeit
the name ``b`` is not particularly descriptive.

The names ``a`` and ``b`` as used in many operators are indeed not very
useful but renaming them wouldn't be a problem since nobody currently
depends on ``a`` or ``b`` in their code; just in the order. That said,
``a`` and ``b`` are not so bad actually, because I couldn't think of
better names for ``a`` and ``b`` in ``operator.contains(a, b)``.

The nice thing now is, that partial can indeed replace many lambdas so
not allowing partial to use operator seems just a random restriction.
msg85093 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2009-04-01 21:03
Sorry, it makes no sense to me to add keyword arguments everywhere just
to accommodate partial().  The alternative using lambda is workable and
there have been proposals to further build-out partial.  I acknowledge
your distaste for lambda but it is firmly a part of the language and we
aren't compelled to have to provide an alternative formulation for every
possible lambda use case.  In the case of the operator module, many of
the functions do not have a natural set of names and so they should
remain nameless -- there is not reason to prefer add(a,b) over add(p,q)
or add(i,j) or add(x,y) -- none of those add any explanatory value to
the reader and are fluff at best and hazardous at worst (for
non-commutative binary operations when a letter can be reasonably
assumed to be either of the two arguments).
History
Date User Action Args
2022-04-11 14:56:46adminsetgithub: 49817
2009-04-01 21:03:56rhettingersetstatus: open -> closed
resolution: rejected
messages: + msg85093
2009-03-26 17:41:31leonidassetmessages: + msg84192
2009-03-26 17:27:42rhettingersetassignee: rhettinger
messages: + msg84189
2009-03-26 16:59:09pitrousetnosy: + rhettinger
2009-03-26 15:48:16leonidascreate