简体   繁体   中英

Implementing __getitem__

Is there a way to implement __getitem__ in a way that supports integer and slice indices without manually checking the type of the argument?

I see a lot of examples of this form, but it seems very hacky to me.

def __getitem__(self,key):
  if isinstance(key,int):
    # do integery foo here
  if isinstance(key,slice):
    # do slicey bar here

On a related note, why does this problem exist in the first place? Somtimes returning an int and sometimes a slice is weird design. Calling foo[4] should call foo.__getitem__(slice(4,5,1)) or similar.

You could use exception handling; assume key is a slice object and call the indices() method on it. If that fails it must've been an integer:

def __getitem__(self, key):
    try:
        return [self.somelist[i] * 5 for i in key.indices(self.length)]
    except AttributeError:
        # not a slice object (no `indices` attribute)
        return self.somelist[key] * 5

Most use-cases for custom containers don't need to support slicing, and historically, the __getitem__ method only ever had to handle integers (for sequences, that is); the __getslice__() method was there to handle slicing instead. When __getslice__ was deprecated, for backwards compatibility and for simpler APIs it was easier to have __getitem__ handle both integers and slice objects.

And that is ignoring the fact that outside sequences, key doesn't have to be an integer. Custom classes are free to support any key type they like.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM