__getitem____iter____next__iter和next的使用方法介绍

Posted 非晚非晚

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了__getitem____iter____next__iter和next的使用方法介绍相关的知识,希望对你有一定的参考价值。

文章目录


最近在使用 __getitem__、__iter__、__next__、iter和next方法时,感到比较困惑,于是抽空把这几个方法放在一起介绍一下,免得自己再犯迷糊。

1. iter和next

(1)iter()

iter(object[, sentinel])
  • object:必须是实现了__iter__()方法或者__getitem__()方法。(如果两个都没有实现,则不能使用iter方法)
  • 如果给定了第二个参数sentinel,则object必须是一个可调用的对象,此时,iter创建了一个迭代器对象,每次调用这个迭代器对象的__next__()方法时,都会调用object。如果__next__的返回值等于sentinel,则抛出StopIteration异常,否则返回下一个值。

(2)next()

next(iterable[, default])
  • iterable – 可迭代对象
  • default – 可选,用于设置在没有下一个元素时返回该默认值,如果不设置,又没有下一个元素则会触发 StopIteration 异常。
  • iter和next普通用法测试

列表、元组、字符串、集合、字典均可使用迭代器

#列表、元组、字符串、集合、字典均可使用迭代器
m_list = [1, 2, 3]
m_tuple = (1,2,3)
m_str = 'qlee'
m_set = 1,2,3
m_dict = 1:'apple', 2:'pear'
print('=============iter测试================')
for i in iter(m_list):
    print(i,end=',') 
print('end list test!')

for i in iter(m_tuple):
    print(i,end=',') 
print('end tuple test!')

for i in iter(m_str):
    print(i,end=',') 
print('end str test!')

for i in iter(m_set):
    print(i,end=',') 
print('end set test!')

for i in iter(m_dict):
    print(i,end=',') 
print('end dict test!')

print('=============next测试================')
my_iter = iter(m_list)
print(next(my_iter))

输出:

=============iter测试================
1,2,3,end list test!
1,2,3,end tuple test!
q,l,e,e,end str test!
1,2,3,end set test!
1,2,end dict test!
=============next测试================
1
  • 自定义iter与next测试
class TestIter(object):
    def __init__(self):
        self.m_list=[1,2,3,4,5,6]
        self.it=iter(self.m_list)
    def __call__(self): 
        item = next(self.it) 
        print ("__call__被调用,此时的next():",item)
        return item
    def __iter__(self):
        print ("__iter__被调用!")
        return iter(self.m_list)

t = TestIter()  # t是可调用的

print('=============iter()测试================')
new_it = iter(t) #此时可以不用定义__call__

print('=============iter(t,2)测试================')
new_it = iter(t, 2)  # t必须是callable的,否则无法返回callable_iterator
print(callable(t))
for i in new_it:
    print(i) #每次调用__call__()

print('=============next()测试================')
new_it = iter(t)
print(next(new_it))

print('=============for循环测试================')
#for循环
new_it = iter(t)
for i in new_it:
    print(i)

输出:

=============iter()测试================
__iter__被调用!
=============iter(t,2)测试================
True
__call__被调用,此时的next()1
1
__call__被调用,此时的next()2
=============next()测试================
__iter__被调用!
1
=============for循环测试================
__iter__被调用!
1
2
3
4
5
6

2. __getitem__方法

其实在之前的文章中有介绍过该方法,它是一种可以把对象当做像字典一样取值,同时还可以使用for循环调用__getitem__方法。

第一节提到了,如果使用__getitem__方法,也可以使用iter函数,同时,执行next()方法时,__getitem__会被执行。下面分别举例介绍。

class DataTest():
    def __init__(self,num):
        self.num=num
        
    def __getitem__(self,index):
        if(index < self.num):
            return "getitem index :" + str(index) + "号"
        else:
            raise StopIteration
    
data=DataTest(3)

print('=============for循环测试================')
new_it = iter(data)
#每次执行一次for循环,就调用一次__getitem__
for i in data:
    print(i)

print('=============类似字典取值================')

#取0,取一次值,则调用一次__getitem__
print(data[1])

# print(data[5]) #StopIteration,超过索引范围

print('=============iter+next测试================')
new_iter = iter(data)
print(next(new_iter))

输出:

=============for循环测试================
getitem index :0号
getitem index :1号
getitem index :2=============类似字典取值================
getitem index :1=============iter+next测试================
getitem index :0

3. __iter__与__next__方法

可在类定义中,手动实现__iter__和__next__方法,如下举例所示。

class DataTest():
    def __init__(self,num):
        self.num = num
        self.start_num = -1
    def __iter__(self):
        print('__iter__被调用')
        return self
    def __next__(self):
        print('__next__被调用')
        self.start_num +=1
        if(self.start_num >= self.num):
            raise StopIteration()
        return self.start_num

data = DataTest(2) #迭代2次
print('=============for循环测试================')
for i in data: 
    print(i)

print('=============next测试================')
data = DataTest(2) #迭代2次
new_iter = iter(data)
print(next(new_iter))

输出:

=============for循环测试================
__iter__被调用
__next__被调用
0
__next__被调用
1
__next__被调用
=============next测试================
__iter__被调用
__next__被调用
0

4. for循环中,__next__方法比__getitem__优先级更高

__getitem__和__next__都可以的实现方法都可以使用for操作,但是当两个都实现的情况下,__next__优先级相对会更高。


# 实验2 循环遍历next,循环遍历中next的优先级高于索引:
class DataTest():
    def __init__(self,num):
        self.num=num
        self.cnt=0
        
    def __getitem__(self,index):
        if(index<self.num):
            return "getitem 被调用:" + str(index) + "号"
        else:
            raise StopIteration

    def __iter__(self):
        print('iter被调用')
        self.cnt=0
        return self


    def __next__(self):
        if(self.cnt<self.num): 
            self.cnt+=1
            return "next被调用:" + str(self.cnt) + "号"
        else:
            print("next结束*********************")
            raise StopIteration
    
 
data=DataTest(3)
print('=============next举例================')
#next优先级高,所以执行next
it1 = iter(data)
print(next(it1))

print('=============索引举例================')
#索引,调用__getitem__
print(data[1])

print('=============for循环举例================')
#实现__getitem__和__next__都可以实现使用for操作,但是__next__优先级更高
for i in data:
    print(i)

print("遍历结束")

输出:

=============next举例================
iter被调用
next被调用:1=============索引举例================
getitem 被调用:1=============for循环举例================
iter被调用
next被调用:1next被调用:2next被调用:3next结束*********************
遍历结束

以上是关于__getitem____iter____next__iter和next的使用方法介绍的主要内容,如果未能解决你的问题,请参考以下文章

迭代器iter(db),db为实例化的类对象,类对象中没有__iter__,但有__getitem__

python中的__iter__ __reversed__ __next__

33.Python面向对象类的专有方法__iter____getitem____getattr____call____new____init__

33.Python面向对象类的专有方法__iter____getitem____getattr____call____new____init__

33.Python面向对象类的专有方法__iter____getitem____getattr____call____new____init__

定制类