2013-02-24 21 views
0

它是如此的复杂,我理解当产量和递归同时发生 我要遍历文件目录与我的代码:在python产量+递归惹恼了我

import os 
def doc_iter(fpath): 
    if os.path.isdir(fpath): 
    for child in os.listdir(fpath): 
     child=os.path.join(fpath,child) 
     print "this is ",child 
     for cn in doc_iter(child): 
     print "i am here1" 
     yield cn 
     print "yiedl1",cn 
    else: 
    print "i am here2" 
    yield fpath 
    print "yield2",fpath 

有一个diretory test,三个子目录test1,test2,test3
在目录test1,有两个文件test11,test12
在目录test2,有两个文件test21,test22
在直接ORY test3,有两个文件test31,test32

>>> a.next() 
this is /home/debian/test/test2 
this is /home/debian/test/test2/test22 
i am here2 
i am here1 
i am here1 
'/home/debian/test/test2/test22' 
>>> a.next() 
yiedl1 /home/debian/test/test2/test22 
yiedl1 /home/debian/test/test2/test22 
yield2 /home/debian/test/test2/test22 
this is /home/debian/test/test2/test21 
i am here2 
i am here1 
i am here1 
'/home/debian/test/test2/test21' 
>>> a.next() 
yiedl1 /home/debian/test/test2/test21 
yiedl1 /home/debian/test/test2/test21 
yield2 /home/debian/test/test2/test21 
this is /home/debian/test/test3 
this is /home/debian/test/test3/test32 
i am here2 
i am here1 
i am here1 
'/home/debian/test/test3/test32' 
>>> a.next() 
yiedl1 /home/debian/test/test3/test32 
yiedl1 /home/debian/test/test3/test32 
yield2 /home/debian/test/test3/test32 
this is /home/debian/test/test3/test31 
i am here2 
i am here1 
i am here1 
'/home/debian/test/test3/test31' 
>>> a.next() 
yiedl1 /home/debian/test/test3/test31 
yiedl1 /home/debian/test/test3/test31 
yield2 /home/debian/test/test3/test31 
this is /home/debian/test/test1 
this is /home/debian/test/test1/test11 
i am here2 
i am here1 
i am here1 
'/home/debian/test/test1/test11' 
>>> a.next() 
yiedl1 /home/debian/test/test1/test11 
yiedl1 /home/debian/test/test1/test11 
yield2 /home/debian/test/test1/test11 
this is /home/debian/test/test1/test12 
i am here2 
i am here1 
i am here1 
'/home/debian/test/test1/test12' 
>>> a.next() 
yiedl1 /home/debian/test/test1/test12 
yiedl1 /home/debian/test/test1/test12 
yield2 /home/debian/test/test1/test12 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

输出惹恼了我,
1.印刷产量1产量2等于?
2.在教科书中至少有两个yield语句运行,据说是when run into yield ,the program will be halt, the next next() make it continue ?? 3.let分析第一个下一个()的输出,为什么在i am here2" 4.what is the function of产生cn`后有两个i am here1
5.如何详细绘制计算树? 6.如果你写一个函数来遍历目录,

bottom=[] 
import os 
def doc_iter(fpath): 
    if os.path.isdir(fpath): 
     for child in os.listdir(fpath): 
      child=os.path.join(fpath,child) 
      doc_iter(child) 
    else: 
     bottom.append(fpath) 
    return bottom 

输出为:

doc_iter("/home/debian/test") 

[ '/家/于Debian /测试/测试2/test22',“/家庭/ Debian的/ home/debian/test3/test32','/ home/debian/test/test21','/ home/debian/test/test31','/ home/debian/test/test〜','/ home/debian/test/test1/test11','/ home/debian/test/test1/test12']

函数和迭代器之间有不同, 功能:

doc_iter(child) 
在迭代

for cn in doc_iter(child): 
    yield 

正是在这个例子中是多么复杂!

+3

该代码将“fun”放入函数中。 – 2013-02-24 01:30:02

+1

如果您还在每个产量之前添加打印语句,您可能会更好地了解发生的情况。当您在打印后打印时,打印只有在* next *'next()'调用之后才会发生,这似乎使事情变得不必要。 – 2013-02-24 01:33:38

+2

为什么不使用os.walk()函数?它也使用发生器,所以你可以很容易地使用next()... – 2013-02-24 01:37:24

回答

1

所以你的例子在这里有点设计,并且导致了大部分(如果不是全部的话)理解yield的工作原理。

walk_dir导致新的根路径的每次迭代被传递到整个功能,这将导致在功能与自己yields

现在你看到打印在同一路径原因,新的迭代因为接下来的每次调用都会更深入地进入目录结构。

因此,每个next()返回下一个目录或文件。你所看到的停止迭代例外是如何成语

for x in something_that_yeilds()知道如何停止。

我会看看这个在iterators, iterable, and generators上写的很棒的文字。