文件
says:
The constructor builds a list whose items are the same and in the same
order as iterable‘s items. iterable may be either a sequence, a
container that supports iteration, or an iterator object. If iterable
is already a list, a copy is made and returned, similar to
iterable[:]…
但是,如果我有一个A类的对象a,它实现__iter __,__ len__和__getitem__,list(a)使用哪个接口来迭代我的对象以及它背后的逻辑是什么?
我的快速实验让我困惑:
class A(object):
def __iter__(self):
print '__iter__ was called'
return iter([1,2,3])
def __len__(self):
print '__len__ was called'
return 3
def __getitem__(self, index):
print '__getitem(%i)__ was called' % index
return index+1
a = A()
list(a)
输出
__iter__ was called
__len__ was called
[1, 2, 3]
首先调用.__ iter__,好吧.但为什么A .__ len__被称为?然后为什么A .__ getitem__没被调用?
然后我把__iter__变成了发电机
而这改变了魔法方法调用的顺序!
class B(object):
def __iter__(self):
print '__iter__ was called'
yield 1
yield 2
yield 3
def __len__(self):
print '__len__ was called'
return 3
def __getitem__(self, index):
print '__getitem(%i)__ was called' % index
return index+1
b = B()
list(b)
输出
__len__ was called
__iter__ was called
[1, 2, 3]
为什么现在首先调用B .__ len__?但为什么然后B .__ getitem__没有被调用,转换是用B .__ iter__完成的?
最让我困惑的是为什么在A和B的情况下__len__和__iter__的调用顺序不同?