tl;dr
print()これにより、 from 、 in file stdout.txt、stderr 出力 (未処理の例外など)などの stdout 出力が file にキャプチャされますstderr.txt。PowerShell から、を使用します
cmd /c pythonw myApp.py 1>stdout.txt 2>stderr.txt)。stdoutをリダイレクトする行為そのものが実際にスクリプトを再び機能させる可能性があることに
注意してください. 警告: この出力リダイレクト手法は、スクリプトを直接呼び出す場合(スクリプト ファイル パスを に渡す場合とは対照的に) 機能しないようです。理由がわかっている場合、および/またはそれがうまくいく場合はお知らせください。pythonwprint
*.pywpythonw.exe
実行するpythonw.exe任意の Python 2.x または 3.x スクリプトの先頭に次を配置します。
import sys, os
if sys.executable.endswith("pythonw.exe"):
sys.stdout = open(os.devnull, "w");
sys.stderr = open(os.path.join(os.getenv("TEMP"), "stderr-"+os.path.basename(sys.argv[0])), "w")
これにより、スクリプトを で実行すると、次のことが保証されますpythonw.exe。
print()への呼び出しと明示的な呼び出しsys.stdout()は事実上無視されます (no-ops)。
- 未処理の致命的な例外を含む標準エラー出力は、ファイルに送信されます
%TEMP%\stderr-<scriptFileName>。%TEMP%一時ファイル用の現在のユーザーのフォルダーを指す標準の Windows 環境変数です。
つまり、上記のコードを使用して、スクリプトが で呼び出されたときにサイレントに失敗した後、ファイルをチェック%TEMP%\stderr-<scriptFileName>pythonw.exeします。
説明については、読み進めてください。
Windows では、pythonw.exeGUI/no-UI-at-all スクリプトを起動するためのものです。これは、標準の入力および出力ストリーム - sys.stdin、sys.stdout、sys.stderrが利用できないことを意味します。
これには2 つの厄介な副作用があります。
print()- which targets sys.stdoutby default -を使用すると、Python 2.x で例外が発生します。
- この問題は Python 3.x で修正されました。
- 未処理の例外
print()(2.x でトリガーされた例外を含む) は、スクリプトをサイレントに中止させます。
- 例外エラー メッセージは
sys.stderrデフォルトで送信されますが、これはこのシナリオでは利用できないものです。
上記のコードは、次の方法でこれらの問題を修正します。
Python 2.x と Python 3.x の違い:
、、、およびを使用してスクリプトを実行するとpythonw.exe、 次sys.stdinのようsys.stdoutになりsys.stderrます。
- Python 2.xの場合:無効なファイル記述子があります
- orに書き込もうとしたときの最終的な結果は、次の例外です。
sys.stdoutsys.stderrIOError: [Errno 9] Bad file descriptor
- 落とし穴:出力バッファリングのため、この例外は、たとえば 4K バイトを出力するまで表面化しない場合があります。(バッファリングされていない出力の場合)で
pythonw.exe呼び出すことにより、即座にそれを誘発できます。-u
print()盲目的にsys.stdout(デフォルトで) 試行するため、遅かれ早かれこの例外が発生します。
- Python 3.xの場合: に設定されています
None
- これは、 が検出されたときにno-op (何もしない) を実行する3.x
print()関数で補完されるため、ステートメントをデフォルトで安全に使用できます。sys.stdoutNoneprint()pythonw.exe
- ただし、使用しようとする
sys.stdout.write()とsys.stderr.write()例外が発生します。
背景の詳細については、こちらを参照してください。