关于可迭iterable理解

引子

在django中执行查询如

queryset = User.objects.all()

查询出来的query是惰性,只有当你调用的时候才会真正去执行sql
比如说print queryset时,才去执行
那么问题来了?他是怎么打印的?

iter的理解

当print的时候,调用下面:

repr(list(self))

显然list()对象实例实例化的时候,需要一个可迭代的(iterable)对象.
什么可迭代的对象?

可迭代(iterable)

-1 支持迭代协议的(the iteration protocol )
__iter__()返回一个具有next()方法的对像.不停调用next(),结束抛出StopItertion异常的

-2 支持序列协议的(the sequence protocol)
__getitem__(self,item) 方法且item从0开始的整数


class Iter(object):
    def __init__(self):
        self.ini = 10

    # def __iter__(self):
    #     print 111
    #     return self
    #
    # def next(self):
    #     print 222
    #     if self.ini < 3:
    #         raise StopIteration
    #     self.ini -= 2
    #     return self.ini

    def __len__(self):
        print 333

    def __getitem__(self, item):
        self.ini -= 1
        if self.ini < 0:
            raise StopIteration
        return item

a = list(Iter())
for i in a:
    print i,

输出

333
0 1 2 3 4 5 6 7 8 9

注意:

  • 1 __iter__()优先级别高于__getitem__,两者都在的时候,前者起作用

  • 2 调用顺序

情况1
__iter__-->__len__-->next

情况2 
__len_--> __getitem__

此外值得注意的一点,迭代器对象只能用一次

a = list(Iter())
for i in a:
    print i,
print "\n"
for i in a:
    print i,
print "\n"
b = iter(Iter())

for i in b:
    print i,
print "\n"
for i in b:
    print 1,
print "\n"

#输出
333
0 1 2 3 4 5 6 7 8 9 

0 1 2 3 4 5 6 7 8 9 

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

推荐阅读更多精彩内容

  • PYTHON-进阶-ITERTOOLS模块小结转自wklken:http://wklken.me/posts/20...
    C_Y_阅读 1,047评论 0 2
  • 内置函数Python解释器内置了许多功能和类型,总是可用的。他们是按字母顺序列在这里。 abs(x)返回一个数的绝...
    uangianlap阅读 1,273评论 0 0
  • 迭代器(Iterable) 简单来说,迭代器对象(my_list)可以让以下代码正常工作: 如果对象实现了__it...
    SOLAREST阅读 574评论 0 1
  • 黛玉兄原创,原文来自公众号“林林总总cr”,新手写文,请多关照。 元宵未至,不管情不情愿,好多人都已早早地回归了工...
    創榮阅读 225评论 0 0
  • say hello to a new world here:)
    微笑的鱼1119阅读 118评论 0 0