import collections


class Fib(object):
    def __init__(self, count=10):
        self.__a, self.__b, self.__n = 0, 1, 0
        self.__count = count

    # 实现了 iter 和 next 就变成了 Iterator
    def __iter__(self):
        return self

    def __next__(self):
        self.__a, self.__b, self.__n = self.__b, self.__a + self.__b, self.__n + 1
        if self.__n > self.__count:
            raise StopIteration()
        return self.__a

    # 可以通过下标获取了
    def __getitem__(self, item):
        # item 是索引
        if isinstance(item, int):
            if item > self.__count - 1:
                raise OverflowError('item is out of the index')
            a, b = 1, 1
            for x in range(item):
                a, b = b, a + b
            return a
        # item 是切片对象slice
        if isinstance(item, slice):
            start = item.start
            stop = item.stop
            if start is None:
                start = 0
            if stop is None:
                stop = self.__count

            if start >= self.__count or start < 0 or stop > self.__count or stop < 0:
                raise OverflowError('item is out of the count')

            a, b = 0, 1
            L = list()
            for x in range(stop):
                a, b = b, a+b
                if x >= start:
                    L.append(a)
            return L


fib = Fib()
# True, True. 注释掉__next__就变成了True False
print(isinstance(fib, collections.Iterable), isinstance(fib, collections.Iterator))

L = list()
for f in fib:
    L.append(f)
# 既可以像list一样访问,也可以迭代器访问,还可以切面访问(暂时未实现逆向切面)
print(fib[9], L, fib[0:4], fib[2:], fib[:5])

# OverflowError: item is out of the count
# print(fib[-1:])
# OverflowError: item is out of the count
# print(fib[:11])
