この文脈から:
import itertools
lines = itertools.cycle(open('filename'))
同じ「機能」を実装するにはどうすればよいのでしょうか。ただし、ファイルが最後に到達したときにファイルを再読み取りするため、最初の反復以降にファイルが変更された場合は、次のサイクルを開始する前に再ロードされます。(私がよく説明したことを願っています)
前もって感謝します!:)
この文脈から:
import itertools
lines = itertools.cycle(open('filename'))
同じ「機能」を実装するにはどうすればよいのでしょうか。ただし、ファイルが最後に到達したときにファイルを再読み取りするため、最初の反復以降にファイルが変更された場合は、次のサイクルを開始する前に再ロードされます。(私がよく説明したことを願っています)
前もって感謝します!:)
私は使用します:
itertools.chain.from_iterable(itertools.starmap(open, itertools.repeat(("filename",))))
また:
itertools.chain.from_iterable(itertools.starmap(lambda: open("filename"), itertools.repeat(())))
ジェネレーターの理解を書くこともできます(私はこれが一番好きだと思います!):
(line for _ in itertools.repeat(()) for line in open("filename"))
命令型(ステートメントベース)の同等物は次のとおりです。
def cycle_file(filename):
while True:
for line in open(filename):
yield line
または、Python 3.3の場合(PEP 380サブジェネレーター委任を使用):
def cycle_file(filename):
while True:
yield from open(filename)
これらすべての問題の1つは、(JythonなどのGCプラットフォームでは)ファイルオブジェクトがGCされるまでファイルが閉じられないことです。これは、しばらくしてから発生する可能性があります。開いているファイルのリークを防ぐには、ファイルを呼び出すclose
か、contextmanager(with
ステートメント)を使用する必要があります。これは、命令形で自然に出てきます。
def cycle_file(filename):
while True:
with open(filename) as f:
for line in f:
yield line
また
def cycle_file(filename):
while True:
with open(filename) as f:
yield from f
ジェネレーターの理解でファイルを閉じようとすると、非常に不自然になります。
(line for f in (itertools.chain(f, (f for f in (f,) if f.close() and False))
for f in (open("filename") for _ in itertools.repeat(())))
for line in f)
Pythonに、ファイルの終わりに達したときにedファイルがそれ自体を閉じるように指定するopen
方法、またはcontextmanager-iteratorにそれ自体を閉じるように指示する方法があると便利StopIteration
です。
何かのようなもの
def cycle_file(f):
while True:
ln = f.readline()
if ln == "":
f.seek(0)
continue
yield ln
空のファイルをチェックするのがいいかもしれないことを除いて、それはあなたに任せます。