Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,取第5个元素:
1
2
3
4
|
>>> Fib()[ 5 ] Traceback (most recent call last): File "<stdin>" , line 1 , in <module> TypeError: 'Fib' object does not support indexing |
要表现得像list那样按照下标取出元素,需要实现__getitem__()方法:
1
2
3
4
5
6
|
class Fib( object ): def __getitem__( self , n): a, b = 1 , 1 for x in range (n): a, b = b, a + b return a |
现在,就可以按下标访问数列的任意一项了:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
>>> f = Fib() >>> f[ 0 ] 1 >>> f[ 1 ] 1 >>> f[ 2 ] 2 >>> f[ 3 ] 3 >>> f[ 10 ] 89 >>> f[ 100 ] 573147844013817084101 |
slice对象与__getitem__
想要使类的实例像列表一样使用下标, 可以设置__getitem__方法。比如:
1
2
3
4
5
6
7
|
class _List( object ): def __getitem__( self , key): print key l = _List() l[ 3 ] # print 3 |
但是如果想要使用切片操作的
1
|
l[ 1 : 4 ] # print slice(1, 4, None) |
会创建一个slice对象用于切片, 可以通过help(slice)查看具体操作。
1
2
3
|
a = slice ( 1 , 4 , None ) range ( 5 )[a] # print [1, 2, 3] |
更加丰富的操作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
class _List( object ): def __init__( self , _list): self ._list = _list def __getitem__( self , key): if isinstance (key, int ): return self ._list[key] elif isinstance (key, slice ): reutrn self .__class__( self ._list[key]) if __name__ = = '__main__' : c = _List( range ( 10 )) b = c[ 1 : 5 ] print b[ 3 ] # print 4 |
如果key是一个整形的话就返回列表元素,如果是一个slice对象的话,就创建一个实例并返回。