今天在学习python的定制类,教程里面展示了如何用__getitem__方法,实现某个类的切片。
python
class Fib(object):
def getitem(self, n):
if isinstance(n, int): # n是索引
a, b = 1, 1
for x in range(n):
a, b = b, a + b
return a
if isinstance(n, slice): # n是切片
start = n.start
stop = n.stop
if start is None:
start = 0
a, b = 1, 1
L = []
for x in range(stop):
if x >= start:
L.append(a)
a, b = b, a + b
return L
廖雪峰大大的教程虽说是“零起点”,但是有些地方确实不太详细,对于初学者来说容易懵逼。比如上面代码中有一段
```python```
isinstance(n,slice)
当时我就想 “What ? ! slice居然也是一种数据类型?!”
于是我尝试通过type来确认,但是结果很糟糕
尝试通过type来确认数据类型slice
我又想,难道slice是一种有限制的数据类型?和本文开头那段代码中一样,只有作为参数时才能是slice类型?
于是我决定定义一个函数来验证我的想法,果不其然,又失败了。
尝试通过定义函数来确认
因为我们之前在切片时,slice总是直接用在序列的后面,如
>>> L = [1,2,3,4,5]
>>> L[2:]
[3, 4, 5]
>>> T = ('a','b','c','d','e')
>>> T[:-2]
('a', 'b', 'c')
所以一般情况下,它根本没办法作为参数传入函数中。
PS:上面我通过type验证失败之后,想通过自定义函数验证其实是多此一举,因为type其实就是一个内置函数。type不成功,自定义函数也不会成功的
那么话说回来,为什么本文开头的那段代码中,slice能被传入并且进行类型判断呢?
仔细看了下教程中传入slice的方式
python
f = Fib()
f[0:5]
[1, 1, 2, 3, 5]
f[:10]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
跟我们对序列使用切片时一毛一样?WTF ?
原来是因为__\_\_getitem\_\_这种带双下划线方法的特殊性__
在本文开头那个例子中,如果类定义了这个\_\_getitem\_\_方法,那么对类进行切片时,切片会作为\_\_getitem\_\_的参数传入,还可以通过start和stop方法获取到切片的两个值…
####妹的,都是套路啊…
网友评论