[Python-ideas] Add "default" kw argument to operator.itemgetter and operator.attrgetter

Danilo J. S. Bellini danilo.bellini at gmail.com
Mon May 7 19:37:02 EDT 2018


(1)

On 7 May 2018 at 01:07, Raymond Hettinger <raymond.hettinger at gmail.com>
wrote:

> He could've written:
>
>     get = rpartial(getattr, 'foo', None)
>     return get(args) or get(config) or get(env)
>

That's somewhat hybrid, it would behave like:

lambda obj: getattr(obj, "foo", None),

but one might expect a "reversed partial" to have its arguments reversed as
well, like:

lambda obj: getattr(obj, None, "foo").

(2)

Why getattr can't accept keyword arguments?

>>> getattr_zero = partial(getattr, default=0)
>>> getattr_zero({}, "blah")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: getattr() takes no keyword arguments

Since partial/partialmethod can apply keyword arguments, allowing the
"default=" keyword argument in getattr would be an alternative to the
"rpartial".

(3)

At one time, lambda was the one obvious way. [...]
>

I really like lambdas, but there are some "closure gotchas" like:

>>> for idx in indices:
...     do_something(lambda seq: seq[idx])

If the lambda is stored somewhere to be called after the loop ends (or
after its iteration), the seq[idx] would load the item with the last
iterated index. This:

>>> for idx in indices:
...     do_something(itemgetter(idx))

would behave more like this instead:

>>> for idx in indices:
...     do_something((lambda i: (lambda seq: seq[i]))(idx))

Which I wouldn't call "the one obvious way".

(4)

If itemgetter and attrgetter only did a single lookup, a default might make
> sense.  However, that doesn't fit well with multiple and/or chained lookups
> where are number of options are possible. (See https://bugs.python.org/
> issue14384#msg316222 for examples and alternatives).

As attrgetter/itemgetter might get heterogeneus data, I would expect a
per-get default, not [just] a global default.
Perhaps something like:

>>> itemgetter(-1, 0, -2,
...            default0="first argument default",
...            default1=["second", "argument", "default"],
...            default={"global": "default"},
... )

-- 
Danilo J. S. Bellini
---------------
"*It is not our business to set up prohibitions, but to arrive at
conventions.*" (R. Carnap)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180507/d4a4919e/attachment.html>


More information about the Python-ideas mailing list