On Sun, Jul 19, 2020 at 10:25 PM Jonathan Goble <jcgoble3@gmail.com> wrote:
On Sun, Jul 19, 2020 at 9:53 PM Stephan Hoyer <shoyer@gmail.com> wrote:
On Fri, Jul 17, 2020 at 9:22 PM Ricky Teachey <ricky@teachey.org> wrote:
>>> # The positional arguments aren't part of the KeyObject
>>> d[a, b:c, d, e=5, f=6] == d.__getitem__((a, b:c, d), KeyObject(e=5, f=6))

This raises a question that needs to be answered, then: what would be the utility of mixing together positional and kwd arguments in this way?

Even the xarray examples given so far don't seem to make use of this mixture. From my knowledge of pandas I am not sure what the meaning of this would be, either.

One use case that comes up in xarray and pandas is support for indicating indexing "modes". For example, when indexing with floating point numbers it's convenient to be able to opt-in to approximate indexing, e.g., something like:
array.loc[longitude, latitude, method='nearest', tolerance=0.001]

I had to stare at this for a good 30 seconds before I realized that this wasn't a function/method call. Except for the square brackets instead of parentheses, it would be.

Honestly, this whole idea smells to me like just wanting another type of function call with different semantics.

IMHO the above example would be better spelled as:

array.loc.get(longitude, latitude, method='nearest', tolerance=0.001)

Pros: Much more obvious, perfectly legal today, zero backward compatibility issues, probably the way many libraries with such functionality are doing it now.
Cons: A few extra characters (depending on the method name; here it's only four) and a couple of taps on the Shift key (but you're already used to that).

Whereas for the indexing example:

Pros: Explicit about indexing a collection and returning an item (but a good method name like "get" also has this quality).
Cons: Not immediately obvious to an uninitiated reader of the code, new syntax, code using it is not compatible with Python 3.9 or earlier.

As for setting a value, the indexing approach has a bit more value (since a function call can't be an lvalue), but you can just change the method name from "get" to "set" and add an extra parameter to be the value to set, and you're done. The pros and cons still apply. 

TL;DR: -1 all the way. Just use ordinary methods.

Another Con for the function call approach, you don't get to use the nice slicing syntax. Compare:

>>> array.loc.get(slice(None), slice(None), method='nearest', tolerance=0.001)
>>> array.loc.get[:, :, method='nearest', tolerance=0.001]

You also can't delete using a function call:

>>> del array.loc.get[:, :, method='nearest', tolerance=0.001]