python若是想让一个类被用于for....in 循环,类型list和tuple那样,能够实现__iter__方法。python
这个方法返回一个迭代对象,python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值,直到遇到StopIteration错误时退出循环。app
class Fib(object): def __init__(self): self.a,self.b=0,1 #初始化两个计数器a,b def __iter__(self): return self #实例自己就是迭代对象,故返回本身 def next(self): self.a,self.b=self.b,self.a+self.b #计算下一个值 if self.a>100000: #退出循环的条件 raise StopIteration() return self.a
把Fib实例做用于for循环:对象
for n in Fib(): print n 1 1 2 3 5 ... 46368 75025
Fib 实例虽然能做用于for循环,看起来和list有点像,可是,把它当成list来使用仍是不行,例如,按下标取元素blog
print Fib()[5]
此时会报错:TypeError: 'Fib' object does not support indexingget
要实现按下标取元素,须要实现__getitem__()方法it
def __getitem__(self,n): a,b=1,1 for x in range(n): a,b=b,a+b return a
按下标获取元素io
f=Fib() print f[0] #1 print f[1] #1 print f[10] #89 print f[100] #573147844013817084101
list 有个切片方法获取元素for循环
print range(100)[5:10] #[5, 6, 7, 8, 9]
对于Fib却报错,缘由是__getitem__传入的参数多是一个int,也多是一个切片对象slice,须要作判断class
def __getitem__(self, n): if isinstance(n, int): a, b = 1, 1 for x in range(n): a, b = b, a + b return a if isinstance(n, slice): start = n.start stop = n.stop a, b = 1, 1 L = [] for x in range(stop): if x >= start: L.append(a) a, b = b, a + b return L
试试Fib的切片object
f=Fib() print f[0:5] #==>[1, 1, 2, 3, 5] print f[:10] # ==>[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]