Pythonの印刷機能を強制的に画面に出力するにはどうすればよいですか?
これはDisable output bufferingの複製ではありません-これはより一般的ですが、リンクされた質問はバッファリングされていない出力を試みています。その質問の上位の回答は強力すぎるか、この質問に関与しています(これは適切な回答ではありません)。この質問は、比較的初心者がGoogleで見つけることができます。
Pythonの印刷機能を強制的に画面に出力するにはどうすればよいですか?
これはDisable output bufferingの複製ではありません-これはより一般的ですが、リンクされた質問はバッファリングされていない出力を試みています。その質問の上位の回答は強力すぎるか、この質問に関与しています(これは適切な回答ではありません)。この質問は、比較的初心者がGoogleで見つけることができます。
回答:
Python 3ではprint
、オプションのflush
引数を取ることができます
print("Hello world!", flush=True)
Python 2ではあなたがしなければならないでしょう
import sys
sys.stdout.flush()
呼び出しprint
た後。デフォルトでは、にprint
出力されますsys.stdout
(ファイルオブジェクトの詳細については、ドキュメントを参照してください)。
Python 3.3以降でprint()
は、を使用せずに通常の関数を強制的にフラッシュできますsys.stdout.flush()
。「flush」キーワード引数をtrueに設定するだけです。ドキュメントから:
print(* objects、sep = ''、end = '\ n'、file = sys.stdout、flush = False)
オブジェクトをsepで区切られ、その後にendが続くストリームファイルに出力します。sep、end、およびfile(存在する場合)は、キーワード引数として指定する必要があります。
キーワード以外のすべての引数は、str()のように文字列に変換されてストリームに書き込まれ、sepで区切られ、その後にendが続きます。sepとendは両方とも文字列でなければなりません。Noneにすることもできます。これは、デフォルト値を使用することを意味します。オブジェクトが指定されていない場合、print()はendを書き込みます。
file引数は、write(string)メソッドを持つオブジェクトでなければなりません。存在しないかNoneの場合、sys.stdoutが使用されます。出力がバッファリングされるかどうかは通常ファイルによって決定されますが、flushキーワード引数がtrueの場合、ストリームは強制的にフラッシュされます。
Python printの出力をフラッシュする方法は?
これを行う5つの方法をお勧めします。
print(..., flush=True)
(flush引数はPython 2のprint関数では使用できません。また、printステートメントに類似のものはありません)。file.flush()
に、出力ファイルを呼び出します(Python 2の印刷機能をラップしてこれを行うことができます)。sys.stdout
print = partial(print, flush=True)
、モジュールグローバルに適用される部分関数を含むモジュール内のすべての印刷関数呼び出しに適用します。-u
、インタプリタコマンドに渡されたフラグ()を使用してプロセスに適用しますPYTHONUNBUFFERED=TRUE
(これを元に戻すには変数を設定解除します)。Python 3.3以降を使用flush=True
すると、print
関数のキーワード引数として指定できます。
print('foo', flush=True)
彼らはflush
引数をPython 2.7にバックポートしなかったので、Python 2(または3.3未満)を使用していて、2と3の両方と互換性のあるコードが必要な場合は、次の互換性コードをお勧めします。(__future__
インポートは、「モジュールの最上部の近く」にある必要があります):
from __future__ import print_function
import sys
if sys.version_info[:2] < (3, 3):
old_print = print
def print(*args, **kwargs):
flush = kwargs.pop('flush', False)
old_print(*args, **kwargs)
if flush:
file = kwargs.get('file', sys.stdout)
# Why might file=None? IDK, but it works for print(i, file=None)
file.flush() if file is not None else sys.stdout.flush()
上記の互換性コードはほとんどの用途をカバーしますが、より完全な扱いについては、six
モジュールを参照してください。
あるいは、file.flush()
たとえばPython 2のprintステートメントを使用して、印刷後に呼び出すこともできます。
import sys
print 'delayed output'
sys.stdout.flush()
flush=True
モジュールのグローバルスコープでfunctools.partialを使用して、print関数のデフォルトを変更できます。
import functools
print = functools.partial(print, flush=True)
少なくともPython 3の新しい部分関数を見ると、
>>> print = functools.partial(print, flush=True)
>>> print
functools.partial(<built-in function print>, flush=True)
通常のように機能することがわかります。
>>> print('foo')
foo
そして、実際に新しいデフォルトを上書きすることができます:
>>> print('foo', flush=False)
foo
繰り返しますが、これは現在のグローバルスコープのみを変更します。現在のグローバルスコープの印刷名が組み込みprint
関数に影を付けるためです(または、現在のグローバルスコープでPython 2で互換性関数を使用している場合は、互換性関数の参照を解除します)。
モジュールのグローバルスコープではなく関数内でこれを実行する場合は、次のように別の名前を付ける必要があります。
def foo():
printf = functools.partial(print, flush=True)
printf('print stuff like this')
関数でグローバルに宣言する場合は、モジュールのグローバル名前空間で変更するので、特定の動作が正確に必要な場合を除き、グローバル名前空間に配置するだけです。
ここでの最良のオプションは、-u
バッファリングされていない出力を取得するためにフラグを使用することです。
$ python -u script.py
または
$ python -um package.module
ドキュメントから:
stdin、stdout、およびstderrが完全にバッファリングされないようにします。重要なシステムでは、stdin、stdout、およびstderrもバイナリモードにします。
このオプションの影響を受けないfile.readlines()およびファイルオブジェクト(sys.stdinの行)には内部バッファリングがあることに注意してください。これを回避するには、while 1:ループ内でfile.readline()を使用します。
環境変数を空でない文字列に設定すると、環境内のすべてのpythonプロセス、または環境から継承する環境でこの動作を得ることができます。
たとえば、LinuxまたはOSXの場合:
$ export PYTHONUNBUFFERED=TRUE
またはWindows:
C:\SET PYTHONUNBUFFERED=TRUE
ドキュメントから:
PYTHONUNBUFFERED
これが空でない文字列に設定されている場合、-uオプションを指定することと同じです。
Python 2.7.12のprint関数のヘルプを次に示します- 引数がない ことに注意してflush
ください:
>>> from __future__ import print_function
>>> help(print)
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
また、このブログで提案されているようにsys.stdout
、バッファなしモードで再開できます。
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
各stdout.write
and print
操作はその後自動的にフラッシュされます。
UnsupportedOperation: IOStream has no fileno.
Python 3.xではprint()
関数が拡張されています:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)
だから、あなたはただ行うことができます:
print("Visiting toilet", flush=True)
-u
コマンドラインスイッチを使用しても機能しますが、少し扱いにくいです。つまり、ユーザーが-u
オプションなしでスクリプトを呼び出した場合、プログラムが正しく動作しない可能性があります。私は通常stdout
、次のようなカスタムを使用します。
class flushfile:
def __init__(self, f):
self.f = f
def write(self, x):
self.f.write(x)
self.f.flush()
import sys
sys.stdout = flushfile(sys.stdout)
...これで、すべてのprint
呼び出し(sys.stdout
暗黙的に使用)が自動的にflush
編集されます。
def __getattr__(self,name): return object.__getattribute__(self.f, name)
バッファリングされていないファイルを使用してみませんか?
f = open('xyz.log', 'a', 0)
または
sys.stdout = open('out.log', 'a', 0)
ダンのアイデアはまったく機能しません。
#!/usr/bin/env python
class flushfile(file):
def __init__(self, f):
self.f = f
def write(self, x):
self.f.write(x)
self.f.flush()
import sys
sys.stdout = flushfile(sys.stdout)
print "foo"
結果:
Traceback (most recent call last):
File "./passpersist.py", line 12, in <module>
print "foo"
ValueError: I/O operation on closed file
問題は、それがファイルクラスから継承されることであり、実際には必要ありません。sys.stdoutのドキュメントによると:
stdoutとstderrは、組み込みのファイルオブジェクトである必要はありません。文字列引数を取るwrite()メソッドがある限り、どのオブジェクトでも使用できます。
とても変わる
class flushfile(file):
に
class flushfile(object):
うまく機能します。
これが私のバージョンで、writelines()とfileno()も提供しています。
class FlushFile(object):
def __init__(self, fd):
self.fd = fd
def write(self, x):
ret = self.fd.write(x)
self.fd.flush()
return ret
def writelines(self, lines):
ret = self.writelines(lines)
self.fd.flush()
return ret
def flush(self):
return self.fd.flush
def close(self):
return self.fd.close()
def fileno(self):
return self.fd.fileno()
file
は、エラーが発生します。file
クラスはありません。
Python 3では、デフォルトの設定で印刷機能を上書きできます flush = True
def print(*objects, sep=' ', end='\n', file=sys.stdout, flush=True):
__builtins__.print(*objects, sep=sep, end=end, file=file, flush=flush)
__future__
バージョンが含まれていないflush
「フラッシュ引数は、Python 3.3(印刷後の()将来のインポートを介して2.7にバックポートされた)を添加した」ためbugs.python.org/issue28458