关于可迭iterable理解

2017-07-15  本文已影响0人  brother阿张

引子

在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__-->__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 
上一篇下一篇

猜你喜欢

热点阅读