引子
在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
网友评论