はじめに
僕はiOSのPythonista3というAppで、よく寝っ転がりながらPythonするのですが、モジュールのヘルプを見ても英語がわからないのでGoogle翻訳が欠かせません。
一度、調べたこともすぐに忘れてしまうので、原文と翻訳テキストを保存しておくことにしました。
モジュールをインポートしてhelp(モジュール)
と入力し、コンソールに出力されるテキストを「すべて選択」し、エディタに張り付けるという作業なのですが、文字数が大きいと選択に時間がかかり、時にはAppが落ちてしまいます。
僕は寝っ転がりながら「コンソールに出力されるテキストを直接ファイルに書き込めたらいいのになぁ。」と普通に思いました。
結論から
import sys
STDOUT = sys.stdout
sys.stdout = open('./tmp.txt', 'w')
help(sys)
sys.stdout = STDOUT
pythonの標準出力の出力先はsys.stdout
になっていて、これを書き換えることで出力先を変更できるそうです。
- まずは、もとに戻れるように
sys.stdout
をSTDOUT
にとっておきます。 - 出力先をファイルに変えます。
- 出力します。
-
sys.stdout
をもとに戻します。
__stdout__
では戻らない
まずは、多くの方が紹介している方法を試してみました。
sys.__stdout__
でもとに戻す方法は、ファイルには出力されるのですが、コンソール出力にに戻らなくなってしまいました。
import sys
sys.stdout = open('./tmp.txt', 'w')
print("Hello")
sys.stdout = sys.__stdout__
print("World!")
Hello
これが、メモに残そうとっしたきっかけなのですが、多くの記事でsys.__stdout__
に戻すだけと紹介されていましたが、僕の環境ではうまく戻すことができませんでした。
ファイルには出力されているのですが、コンソールには何も表示されません。
一瞬、あせりましたが、Appを再起動したらもとに戻ってたので、「あせって損した」と思いながらドキュメントを見ることにしました。
Python 3.10.6 ドキュメント
sys --- システムパラメータと関数
sys.__stdin__
sys.__stdout__
sys.__stderr__
それぞれ起動時の stdin, stderr, stdout の値を保存しています。終了処理時に利用されます。また、 sys.std* オブジェクトが(訳注:別のファイルライクオブジェクトに)リダイレクトされている場合でも、実際の標準ストリームへの出力に利用できます。
また、標準ストリームが壊れたオブジェクトに置き換えられた場合に、動作する実際のファイルを復元するために利用することもできます。しかし、明示的に置き換え前のストリームを保存しておき、そのオブジェクトを復元る事を推奨します。注釈 一部の条件下では、stdin, stdout, stderr も、オリジナルの stdin, stdout, stderr も None になることがあります。これはコンソールに接続しない Windows GUI アプリケーションであり、かつ pythonw で起動された Python アプリケーションが該当します。
つまり
寝っ転がるのをやめて、win10のコマンドプロンプトで試したら、sys.__stdout__
で戻りました。
ついでに、PyhtonIDLEで試したら戻りませんでした。
つまり、「環境によってsys.__stdout__
は使えない場合があるよ。」と理解しました。