Pythonはどのくらいの頻度でファイルにフラッシュしますか?


228
  1. Pythonはどのくらいの頻度でファイルにフラッシュしますか?
  2. Pythonはどのくらいの頻度で標準出力にフラッシュしますか?

(1)についてはわかりません。

(2)に関しては、Pythonは新しい行ごとにstdoutにフラッシュすると思います。しかし、stdoutをオーバーロードしてファイルにした場合、それは頻繁にフラッシュされますか?

回答:


332

ファイル操作の場合、特に設定しない限り、Pythonはオペレーティングシステムのデフォルトのバッファリングを使用します。バッファサイズ、バッファなし、またはラインバッファ付きを指定できます。

たとえば、open関数はバッファサイズ引数を取ります。

http://docs.python.org/library/functions.html#open

「オプションのバッファリング引数は、ファイルの必要なバッファサイズを指定します。」

  • 0はバッファなしを意味し、
  • 1は行バッファリングを意味し、
  • その他の正の値は、そのサイズの(ほぼ)バッファーを使用することを意味します。
  • ネガティブバッファリングとは、システムデフォルトを使用することを意味します。これは通常、ttyデバイスでは行バッファリングされ、他のファイルでは完全バッファリングされます。
  • 省略した場合、システムのデフォルトが使用されます。

コード:

bufsize = 0
f = open('file.txt', 'w', buffering=bufsize)

23
「ラインバッファリングされた」部分の+1。それはまさに私が探していたものであり、それは魅力のように機能します。
手綱

2
Python 3.4.3を使用するopen('file.txt', 'w', 1)と、適切なラインバッファリングが得られます。しかし、私がもっと大きなことをした場合(私が欲しかったopen('file.txt', 'w', 512))それは完全にバッファリングしますio.DEFAULT_BUFFER_SIZE、8192のになります。それは、Pythonのバグ、Linuxのバグ、またはID10tのバグですか?
Bruno Bronosky、2017

すでに開いているバッファリングを変更することは可能ですか?ストリームのですか?たとえば、stdoutコンソールであるか、ファイルにリダイレクトされるかに関係なく、ラインバッファリングを行いたいですか?
ミハイルT.

1
@CharlieParker write()がファイルハンドルを呼び出すと、出力はメモリにバッファリングされ、バッファがいっぱいになるまで蓄積されます...バッファが「フラッシュ」されます(コンテンツがバッファからファイルに書き込まれます)。flush()ファイルハンドルでメソッドを呼び出すことにより、バッファを明示的にフラッシュできます。
Corey Goldberg

3
unbuffered(0)はバイナリモードでのみ使用でき、line buffered(1)はテキストモードでのみ使用できることに注意してください。
ZaydH 2019年

172

flush()メソッドを使用して、プログラムでバッファをファイルに強制的にフラッシュすることもできます。

with open('out.log', 'w+') as f:
    f.write('output is ')
    # some work
    s = 'OK.'
    f.write(s)
    f.write('\n')
    f.flush()
    # some other work
    f.write('done\n')
    f.flush()

これは、出力ファイルをでテーリングするときに便利ですtail -f


54
文書から:Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam

1
@bobismijnnaam次回は上記のドキュメントへのリンク。私が見つけることができる参照はgithub.com/jprzywoski/python-reference/blob/master/source/docs/…からのものであり、それが誰なのかわかりません。
Bruno Bronosky 2017年

5
@Bruno Bronosky良い点。ドキュメント: Note: flush() does not necessarily write the file’s data to disk. Use flush() followed by os.fsync() to ensure this behavior.
bobismijnnaam 2017年

私が混乱しているのは、この用語がflushing意味することです。なぜそれが必要なのですか?それは何のため?なぜ私はそれを気にする必要がありますか?
チャーリーパーカー

@CharlieParkerを書き込むときは、RAM内のファイル(の一部)のコピーに書き込みますが、しばらくの間ディスクに保存されない場合があります。パフォーマンスは向上しますが、そのコピーが書き込まれない場合(ディスクが取り外された場合、OSがクラッシュした場合など)、データが失われる可能性があります。flush()は、そのバッファをすぐにディスクに書き戻すようにPythonに指示します。(そして、os.fsync()はOSにもそれを行うように指示します。バッファには多くの層があります...)
Rena

13

これがpythonにも当てはまるかどうかはわかりませんが、実行しているオペレーティングシステムに依存すると思います。

たとえば、Linuxでは、ターミナルへの出力は改行でバッファーをフラッシュしますが、ファイルへの出力では、バッファーがいっぱいになった場合(デフォルト)にのみフラッシュします。これは、バッファをフラッシュする回数が少ないほうが効率的であり、出力がファイルの改行でフラッシュされない場合でも、ユーザーが気付かない可能性が高いためです。

必要に応じて、出力を自動フラッシュできる場合があります。

編集:私はあなたがこの方法でPythonで自動フラッシュすると思う(ここからベース)

#0 means there is no buffer, so all output
#will be auto-flushed
fsock = open('out.log', 'w', 0)
sys.stdout = fsock
#do whatever
fsock.close()

12

ioモジュールから読み取り専用のDEFAULT_BUFFER_SIZE属性を呼び出して、デフォルトのバッファーサイズを確認することもできます。

import io
print (io.DEFAULT_BUFFER_SIZE)

1
ありがとう!PythonがOSの定義どおりに設定することを知っおくのは良いことですが、これはOSが事前に定義しているものを見つけるのに役立ちます。
Cometsong 2018年

2

OPがどちらを好むかを選択する別のアプローチを次に示します。

以下のコードを__init__他のコードの前に.pyファイルに含めると、出力されたメッセージprintとエラーはAbletonのLog.txtではなく、ディスク上の別のファイルに記録されます。

import sys

path = "/Users/#username#"

errorLog = open(path + "/stderr.txt", "w", 1)
errorLog.write("---Starting Error Log---\n")
sys.stderr = errorLog
stdoutLog = open(path + "/stdout.txt", "w", 1)
stdoutLog.write("---Starting Standard Out Log---\n")
sys.stdout = stdoutLog

(Macの場合、変更 #username#は、ユーザーフォルダーの名前にします。Windowsでは、ユーザーフォルダーへのパスの形式が異なります)

ディスク上のファイルが変更されたときに内容を更新するテキストエディターでファイルを開くと(Macの例:TextEditではなくTextWranglerでは変更されます)、ログがリアルタイムで更新されます。

クレジット:このコードは主にNathan RamellaによってliveAPIコントロールサーフェススクリプトからコピーされました

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.