royce3
royce3

Reputation: 1432

proper pythonic way to allow integer index or a iterator of indexes?

What is the proper pythonic way to allow an integer index or a iterator of indexes?

I've implemented a grid widget for the project I'm working on, and I realized I wanted my users to be able to select multiple rows/columns simultaneously. However, I'd like to not require them to use an iterator to indicate a single row/column selection.

Below is some demonstration code that I have working, but it doesn't feel like the right solution:

def toIter ( selection ):
    if selection is None:
        return []
    elif isinstance ( selection, int ):
        return (selection,)
    else:
        return selection

def test ( selection ):
    for col in toIter(selection):
        print(col) # this is where I would act on the selection

test ( None )
test ( 7 ) # user can indicate a specific column selected...
test ( range(3,7) ) # or a tuple/range/list/etc of columns...

EDIT: added the ability to use None to indicate no selection...

2nd EDIT: I'd really think python should be able to do this, but it complains that integer and NoneType aren't iterable:

def test ( selection ):
    for col in selection:
        print(col)

Upvotes: 1

Views: 67

Answers (1)

tzaman
tzaman

Reputation: 47820

You probably just want to override __getitem__ in your widget class, and support integers as well as slices. Something like this:

class Widget(object):
    def __getitem__(self, selection):
        if isinstance(selection, int):
            #return selected col
        elif isinstance(selection, slice):
            #return cols based on selection.start/stop/step
        else:
            raise TypeError('bad selection')

Which you can then use like:

w = Widget()
w[4] # get 4th col
w[8:16] # get 8-16th cols

You could also enhance this to support 2-dimensional access via tuple-of-slices, accessible like w[1:4, 5:8].

Upvotes: 1

Related Questions