__getitem__

上一篇的 Fib 实例虽然能作用于 for 循环,看起来和 list 有点像,但是,把它当成 list 来使用还是不行,比如,取第5个元素:

>>> Fib()[5]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'Fib' object does not support indexing

要表现得像 list 那样按照下标取出元素,需要实现 __getitem__() 方法。

先用最简单的例子看看 __getitem__() 方法的用法:

class Fib(object):
    
    def __getitem__(self, n):
        return n*n

测试:

>>> f = Fib()
>>> f[1]
1

>>> f[5]
25

接下来我们实现斐波拉契数列:

class Fib(object):
    def __getitem__(self, n):
        a, b = 1, 1
        for x in range(n):
            a, b = b, a + b
        return a

现在,就可以按下标访问数列的任意一项了:

>>> f = Fib()
>>> f[0]
1
>>> f[1]
1
>>> f[2]
2
>>> f[3]
3
>>> f[10]
89
>>> f[100]
573147844013817084101

但是 Fib 还不能像 list 那样使用切片操作,原因是 __getitem__() 传入的参数可能是一个 int,也可能是一个切片对象 slice,所以要做判断:

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

现在试试 Fib 的切片:

>>> f = Fib()
>>> f[0:5]
[1, 1, 2, 3, 5]

>>> f[:10]
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

但是没有对 step 参数作处理,也没有对负数作处理,所以,要正确实现一个 __getitem__() 还是有很多工作要做的。

此外,如果把对象看成 dict__getitem__() 的参数也可能是一个可以作 keyobject,例如 str

与之对应的是 __setitem__() 方法,把对象视作 listdict 来对集合赋值。最后,还有一个 __delitem__() 方法,用于删除某个元素。

总之,通过上面的方法,我们自己定义的类表现得和 Python 自带的 listtupledict 没什么区别,这完全归功于动态语言的“鸭子类型”,不需要强制继承某个接口。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • __getitem__使类具有list、tuple、dict类型的方法,如取下标,切片之类的操作 与之对应的是se...
    徐子鑑阅读 3,644评论 0 0
  • pyton review 学习指南 https://www.zhihu.com/question/29138020...
    孙小二wuk阅读 4,716评论 0 2
  • 首先,我坦白一点我十分害怕写作,具体缘由要追溯到上学那会。 上学那会,作文一直是我的弱项。临场写作文,我总是头皮硬...
    杜可是个神经病阅读 1,774评论 0 0
  • 以前看过一篇小说,钱钟书的,叫做围城,城里的人想出去,外面的人想进来。有时候,婚姻何尝不是一座围城!最近看一篇文章...
    悠哉的蜗牛阅读 1,560评论 0 0
  • 桥上蹦一蹦 啃一棱西瓜 闻闻 母马的味道 姑娘,你脚 脖子上 开得什么花
    小j_阅读 806评论 0 2