列表,字典,字符串,元祖都是可迭代对象(Iterable),这就意味着它们是可以使用 for循环 进行遍历。
检测是否是可迭代对象的方法 isinstance()
from collections import Iterable
result=isinstance([1,2],Iterable)
print('列表',result)
result=isinstance((1,2),Iterable)
print('元祖',result)
result=isinstance({1:'2'},Iterable)
print('字典',result)
result=isinstance('sss',Iterable)
print('字符串型',result)
result=isinstance(100,Iterable)
print('int型',result)
列表 True
元祖 True
字典 True
字符串型 True
int型 False
制作一个迭代器,需要包含 **iter()函数与next()函数**,如下:
from collections import Iterable
class my_iterable():
def __iter__(self):
pass
def __next__(self):
pass
ii=my_iterable()
result=isinstance(ii,Iterable)
print(result)
True
<font color=#D2691E size=3>当拥有了这两个函数,便被承认为一个可迭代对象
<font face='黑体' color=# size=3>**自定义一个迭代器**
# 1、MyList类
class MyList(object):
# 1)初始化方法
def __init__(self):
# 定义实例属性,保存数据
self.items = []
# 2)__iter__() 方法,对外提供迭代器
def __iter__(self):
# 创建MyListIterator 对象
mylist_iterator = MyListIterator(self.items)
# 返回迭代器
return mylist_iterator
# 3)addItem() 方法,用来添加数据
def addItem(self, data):
# 追加保存数据
self.items.append(data)
print(self.items)
# 2、自定义迭代器类:MyListIterator
class MyListIterator(object):
# 1) 初始化方法
def __init__(self, items):
# 定义实例属性,保存MyList类传递过来的items
self.items = items
# 记录迭代器迭代的位置
self.current_index = 0
# 2)迭代器方法 __iter__()
def __iter__(self):
pass
# 3) 获取下一个元素值的方法 __next__()
# next(mylist_iterator) 就会调用 __next__() 方法
def __next__(self):
# 1、 判断当前的下标是否越界
if self.current_index < len(self.items):
# 1)根据下标获取下标对应的元素值
data = self.items[self.current_index]
# 2)下标位置 +1
self.current_index += 1
# 3)返回下标对应的数据
return data
# 如果越界,直接抛出异常
else:
# raise 用于主动抛出异常
# StopIteration 停止迭代
raise StopIteration
if __name__ == '__main__':
# 1、创建自定义列表对象
mylist = MyList()
mylist.addItem("张飞")
mylist.addItem("关羽")
mylist.addItem("班长")
mylist.addItem("xxxxx")
# 遍历
# 1) iter(mylist) 获取 mylist对象的迭代器 --> MyList --> __iter__()
# 2)next(迭代器) 获取下一个值
# 3)捕获异常
# for value in mylist:
# print("name:", value)
mylist_iterator = iter(mylist)
# value = next(mylist_iterator)
# print(value)
#
# value = next(mylist_iterator)
# print(value)
3.生成器
生成器是一种特殊的迭代器,它更加便捷
创建生成器的第一种方法
1 . 列表推导式创建法(将列表推导式外面的 [] 变成())
kk=(aa*2 for aa in range(20))
2 . yeid创建
def work1():
yield 10 # 程序执行到yield语句的时候,程序暂停,返回yield后面表达式的值,在下一次调用的时候,从yield语句暂停的地方继续执行
yield 100
kk=work1()
value=next(kk)
print(value)
## 4 . 协程
从技术的⻆度来说,“协程就是你可以暂停执⾏的函 数”。如果你把它理解成“就像⽣成器⼀样”,那么你就想对了。
协程存在的意义:对于多线程应⽤,CPU通过切⽚的⽅式来切换线程间的执⾏,线程切换时需要 耗时(保存状态,下次继续)。协程,则只使⽤⼀个线程(单线程),在⼀个线程中规定某个代码块 执⾏顺序
①第一种协程方式
import time
def work1():
while True:
print('正在执行work1')
yield #执行大yield会暂停并保存当前状态,随即去处理work2
time.sleep(0.5) #加时间延迟方便观察
def work2():
while True:
print('正在执行work2')
yield #执行大yield会暂停并保存当前状态,随即去处理work1
time.sleep(0.5)
if __name__ == '__main__':
w1 = work1()
w2 = work2()
while True:
next(w1)
next(w2)
②第二种协程方式
import time
from greenlet import greenlet
def work1():
while True:
print('正在运行work1')
time.sleep(0.5)
w2.switch()
def work2():
while True:
print('正在执行work2')
time.sleep(0.5)
w1.switch()
if __name__ == '__main__':
w1=greenlet(work1)
w2=greenlet(work2)
w1.switch()
③第三种协程方式(常用重要必记)
import time
import gevent #gevent 可以自动识别耗时代码然后切换到另一个任务
from gevent import monkey
monkey.patch_all() # 破解所有未识别的命令
def work1():
while True:
print('正在执行work1...')
time.sleep(0.3)
def work2():
while True:
print('正在执行work2...')
time.sleep(0.3)
if __name__ == '__main__':
# 指派任务
g1=gevent.spawn(work1) # gevent.spawn(函数名,参数1,参数2,参数3....)
g2=gevent.spawn(work2)
g1.join() # join 阻塞,让主进程等待协程运行。
g2.join()