todaygood / python_repo

study python examples,kb.
0 stars 0 forks source link

yield 程序如何理解啊? #1

Open todaygood opened 6 years ago

todaygood commented 6 years ago
#!/usr/bin/env python

def yield_test(n): 
    for i in range(n):
        print("in i=",i)  
        yield call(i)  
        print("out i=",i)  
    #做一些其它的事情      
    print("do something.")      
    print("end.")  

def call(i):  
    return i*2  

#使用for循环  
for i in yield_test(5):  
    print(i,",")

运行结果:

(py3) [root@mycentos7 python_repo]# ./yield_mh.py 
in i= 0
0 ,
out i= 0
in i= 1
2 ,
out i= 1
in i= 2
4 ,
out i= 2
in i= 3
6 ,
out i= 3
in i= 4
8 ,
out i= 4
yuanaisha commented 6 years ago

主要用于协程中,遇到yield后中断return,去执行另一个子程序,并且通常可以使用yield返回一个有用的值,类似C语言中的指针,指向下一个要执行的地址。子程序执行完后,可以使用next或者send方法唤醒,接着刚刚的中断继续执行

todaygood commented 6 years ago

@yuanaisha 我不明白这里:

for i in yield_test(5):  
    print(i,",")

为何输出0,2, 4, 而1 不输出?

todaygood commented 6 years ago

https://www.jianshu.com/p/d09778f4e055 http://blog.jobbole.com/28506/ http://kissg.me/2016/04/09/python-generator-yield/

mylist = [x*x for x in range(3)]
for i in mylist :
print(i)
0
1
4

mylist定义了一个generator , 只能迭代3次, i是从0,开始,取0,1,2 i=0, mylist=0 i=1, mylist=1 i=2, mylist=4

for i in yield_test(5):
print(i,",") i=0, yield_test(5)遍历执行一次, 打印in i=0; 0, i=1, yield_test(5)遍历执行一次, 打印out i=0(上一次遍历时的i值), 2 i=2, yield_test(5)遍历执行一次, 打印out i=1, in i=2, 4 i=3, yield_test(5)遍历执行一次, 打印out i=2, in i=3, 6 i=4, yield_test(5)遍历执行一次,打印out i=3,in i=4, 8 最后,yield_test(5)遍历执行一次,打印out i=4 ,遍历结束。

for ... in .. ,实际上是 执行一次next() ,是进行遍历用的,只能往前, 不能把 yield_test(5)当做一个函数, 这样就好理解一点。

yuanaisha commented 6 years ago

是的,yield相当于中断,下一次外循环进来后,内循环还是按照之前中断的节奏往下进行,所以总共in和out是5对,而不是5*5次。yield不受外部函数影响,除非使用send函数传参进来。