0

イールドと再帰が同時に発生するタイミングを理解するのは非常に複雑です。コードを使用してファイルディレクトリをトラバースしたい:

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

ディレクトリがあり、その中testに3つの子 ディレクトリがあります。ディレクトリに2つのファイルがあります。 ディレクトリに2つのファイルがあります 。ディレクトリに2つのファイルがあります。test1,test2,test3
test1test11,test12
test2test21,test22
test3test31,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
ステートメントが少なくとも2つあります。when run into yield ,the program will be halt, the next next() make it continue3.最初のnext()の出力を分析し ましょう。yieldcn`i am here1の後に2つのsがあるのはなぜですか? 5.計算ツリーを詳細に描く方法は?6.ディレクトリをトラバースする関数を作成する場合、i am here2" 4.what is the function of

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")  

['/ home / debian / test / test2 / test22'、'/ home / debian / test / test2 / test21'、'/ home / debian / test / test'、'/ home / debian / test / test3 / test32' 、'/ home / debian / test / test3 / 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 

この例では、どれほど複雑です。

4

1 に答える 1

1

したがって、ここでの例は少し不自然であり、どのように機能するかを理解するのに苦労しているすべてではないにしても、ほとんどのことにつながりますyield

反復のたびにwalk_dir新しいルート パスが関数全体に渡され、その結果、独自の関数を持つ関数の新しい反復が行われます。yields

同じパスが出力されているのは、next を呼び出すたびにディレクトリ構造の奥深くに移動するためです。

したがって、それぞれnext()が次のディレクトリまたはファイルを返します。あなたが見ている停止反復例外は、イディオムがどのように

for x in something_that_yeilds()停止する方法を知っています。

iterators、iterable、および generatorsに関するこの非常に素晴らしい記事を見てみたいと思います。

于 2013-02-24T01:47:42.857 に答える