如何在类中定义索引方法(__getitem__尝试)

时间:2016-12-20 20:18:01

标签: python python-3.x indexing

我是python中的oop新手 下面是一个类似于range()的mathod的类,除了它包含范围边界。

我正在尝试在类中创建索引方法,以便在调用特定索引时返回具有该索引的元素。我读到__getitem__可以执行索引但我没有成功地正确实现它。如果有更有效的方式不一定使用__getitem__,请提供建议。

请看下面的代码,这是一个简单的代码,旨在学习如何创建类。

def __getitem__(self,index)开始的方法是不起作用的方法,这对应于在结尾o[4]调用索引,这是我想要实现的。

class inclusive_range:
    def __init__(self, *args):
        numargs = len(args)
        if numargs < 1: raise TypeError('requires at least one argument')
        elif numargs == 1:
            self.stop = args[0]
            self.start = 0
            self.step = 1
        elif numargs == 2:
            (self.start,self.stop) = args
            self.step = 1
        elif numargs == 3:
            (self.start,self.stop,self.step) = args
        else:
            raise TypeError('three arguments required at most, got {}'.format(numargs))

    def __iter__(self):     # this makes the function (the method) and iterable function
        i = self.start  
        while i <= self.stop:
            yield i
            i += self.step

    def __getitem__(self,index):
        return self[index]
        print(self[index])

def main():
    o = inclusive_range(5, 10, 1)
    for i in o: print(i, end=' ')
    o[2]

if __name__ == "__main__": main()

谢谢

1 个答案:

答案 0 :(得分:4)

您可以根据self.start,索引和步长来计算数字。为了使您的对象成为正确的序列,您还需要一个长度,在测试边界时会派上用场:

def __len__(self):
    start, stop, step = self.start, self.stop, self.step
    if step < 0:
        lo, hi = stop, start
    else:
        lo, hi = start, stop
    return ((hi - lo) // abs(step)) + 1

def __getitem__(self, i):
    length = len(self)
    if i < 0:
        i += length
    if 0 <= i < length:
        return self.start + i * self.step
    raise IndexError('Index out of range: {}'.format(i))

以上内容基于my own translation of the range() source code to Python,并进行了一些小调整,以说明最终的包容性。

我会将__len__结果缓存到__init__,以避免每次想知道长度时都重新计算。