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对象的话,就创建一个实例并返回。