美文网首页
关于可迭iterable理解

关于可迭iterable理解

作者: brother阿张 | 来源:发表于2017-07-15 23:15 被阅读0次

    引子

    在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 
    

    相关文章

      网友评论

          本文标题:关于可迭iterable理解

          本文链接:https://www.haomeiwen.com/subject/iabzhxtx.html