This has been discussed.  The current consensus approach would be to keep
the index argument as a single value, while making keyword indices as
keyword arguments.  So something like:

def __getitem__(self, index, **kwargs):

Classes that don't want to handle keyword indices just don't have to
implement handling for keyword arguments.

This has the advantage that it makes it easier to hard-code dimension
labels if desired.  Although I haven't heard from pandas devs on this,
where dataframes are fixed at having two dimensions, "row" and "column" ,
you could potentially implement something like:

def __getitem__(self, index, row=None, column=None):

No special work would be needed to check whether the keywords match, which
would be needed with a new class.

On Thu, Aug 20, 2020 at 1:42 PM Christopher Barker <python...@gmail.com>
wrote:

> I have not fully thought this out yet, but while my first instinct was to
> agree with others to “just use the calling conventions we already have”,
> there is a wrinkle:
>
> Current indexing behavior is an oddball now:
>
> ( you all know this, but I think it’s helpful to lay it out)
>
> The signature of __getitem__ is always:
>
> def __getitem__(self, index):
>
> If you pass a single item:
>
> an_object[thing]
>
> then that thing gets assigned to index, whatever it is.
>
> if you pass more than one item:
>
> an_object(thing1, thing2, thing3)
>
> then a tuple of those gets assigned to index, and the implementation of
> __getitem__ has to parse that out itself, which is different than the
> "usual" argument passing, where it would always be a tuple, whether is was
> a length-one or not. (and to get that tuple, you'd need to use *args, or
> specify a particular number of arguments.
>
> So: if we want to maintain backward compatibility, we *can't* use the
> regula rargument passing approach, it will have to be a slightly odd
> special case.
>
> Which brings us to (what I think is) Jonathan's idea: we keep the idea
> that __getitem__ always accepts a single argument.
>
> now it's either a single object or a tuple of objects. If we extend that,
> then it's either a single object, or a tuple of opjects, or a new
> "keywords" object that would hold both the positional and keyword
> "arguments", so any old code that did somethign like:
>
> def __getitem__(self, index):
>     if isinstance(index, tuple):
>         handle_the_tuple_of_indices(index)
>     else:
>         handle_a_single_index(index)
>
> would still work as it does now.
>
> and if something wanted to implement keywords, it could add a clause:
>
> elif isinstance(index, keywords_object):
>     handle_all_the_args_and_keywords(index)
>
> and away we go.
>
> TL;DR:
> Indexing would now create one of:
> - a single item
> - a tuple of items
> - a keywords_object_of positional and keyword arguments.
>
> And just like we can now create a tuple of indices and pass them in as a
> single object, we could also create a keyword_object some other way and
> pass that in directly.
>
> If we did not do this, could we use:
>
> an_object[*args, **kwargs]
>
> and if *args was length-1, it would get extracted from the tuple? or would
> the seroth item of *args always get extracted from the tuple?
>
> So creating a new object to hold the arguments of an indexing operation is
> a bit awkward, yes, but more consistent with how it currently works.
>
> -CHB
>
>
> On Thu, Aug 20, 2020 at 9:55 AM Jonathan Fine <jfine2...@gmail.com> wrote:
>
>> Todd wrote:
>>
>> It has the same capabilities, the question is whether it has any
>>> additional abilities that would justify the added complexity.
>>>
>>
>> The most obvious additional ability is that always
>>     >>> d[SOME_EXPRESSION]
>> is equivalent to
>>     >>> d[key]
>> for a suitable key.
>>
>> This is a capability that we already have, which would sometimes be lost
>> under the scheme you support.  Also lost would be the equivalence between
>>    >>> val = d[key]
>>    >>> getter = operator.itemgetter(key)
>>    >>> val = getter(d)
>>
>> More exactly, sometimes it wouldn't be possible to find and use a key.
>> Docs would have to be changed.
>> See: https://docs.python.org/3/library/operator.html#operator.itemgetter
>>
>> As I understand it, xarray uses dimension names to slice data.  Here's an
>> example from
>>
>> http://xarray.pydata.org/en/stable/indexing.html#indexing-with-dimension-names
>>     >>> da[dict(space=0, time=slice(None, 2))]
>>
>> Presumably, this would be replaced by something like
>>     >>> da[space=0, time=:2]
>>
>> Now, the commands
>>    >>> da[space=0, time=:2]
>>    >>>  da[space=0, time=:2] = True
>>    >>> del da[space=0, time=:2]
>> would at the begging of the call, presumably, do the same processing on
>> the keyword arguments. (Let this stand for a wide range of examples.)
>>
>> It is arguable that making it easier for the implementer of type(da) to
>> do all that processing in the same place would be a REDUCTION of
>> complexity.  Allowing the processing to produce an intermediate object, say
>>     >>> key = dict(space=0, time=slice(None, 2))
>>  would help here.
>>
>> Real world examples are required, I think, to ground any discussions of
>> complexity and simplicity. We want to optimise for what people do, for the
>> problems they face. And this is a new feature.
>>
>> We have a perfectly good way of handling keywords, so it is up to you to
>>> explain why we shouldn't use it.
>>>
>>
>> The scheme you support does not distinguish
>>     >>> d[1, 2, x=3, y=4]
>>     >>> d[(1, 2), x=3, y=4]
>> I don't regard that as being perfectly good.
>>
>> In addition, I would like
>>     >>> d = dict()
>>     >>> d[x=1, y=2] = 5
>> to work. It works out-of-the-box for my scheme. It can be made to work
>> with a subclass of dict for the D'Aprano scheme.
>>
>> I think that is enough for now.
>>
>> I'd prefer to discuss this further by writing Python modules that contain
>> code that can be tested. The testing should cover both the technical
>> correctness and the user experience. To support this I intend not to focus
>> on the next version of kwkey.
>> https://pypi.org/project/kwkey/
>>
>> --
>> Jonathan
>>
>>
>> _______________________________________________
>>
>> Python-ideas mailing list -- python-ideas@python.org
>>
>> To unsubscribe send an email to python-ideas-le...@python.org
>>
>> https://mail.python.org/mailman3/lists/python-ideas.python.org/
>>
>> Message archived at
>> https://mail.python.org/archives/list/python-ideas@python.org/message/3XRS7WVSFJAZJ6TODL62KZYEDRUV3CRI/
>>
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>>
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/FEPRHQRVPWFCPKAZAKNWN2VB4RUKSTNF/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to