web-dev-qa-db-ja.com

Sys.stdout.writeとprintの違いは?

sys.stdout.write()printより望ましいという状況はありますか?

例: より良いパフォーマンス;もっと理にかなったコード)

314
Johanna Larsson

printは、入力をフォーマットし(変更可能ですが、デフォルトでは引数と改行の間にスペースを入れて)、指定されたオブジェクトの書き込み関数を呼び出す薄いラッパーです。デフォルトではこのオブジェクトはsys.stdoutですが、 "chevron"形式を使ってファイルを渡すことができます。例えば:

print >> open('file.txt', 'w'), 'Hello', 'World', 2+3

参照してください: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement


Python 3.xでは、printが関数になりますが、file引数のおかげでsys.stdout以外のものを渡すことはまだ可能です。

print('Hello', 'World', 2+3, file=open('file.txt', 'w'))

https://docs.python.org/3/library/functions.html#print を参照してください。


Python 2.6以降では、printはまだステートメントですが、以下のように関数として使うことができます。

from __future__ import print_function

更新:コメントでBakuriuが指摘したprint関数とprint文の間に(そしてより一般的には関数と文の間に)少し違いがあります。

引数の評価時にエラーが発生した場合

print "something", 1/0, "other" #prints only something because 1/0 raise an Exception

print("something", 1/0, "other") #doesn't print anything. The func is not called
254
luc

printは最初にオブジェクトを文字列に変換します(まだ文字列でない場合)。行の先頭ではなく、最後に改行文字でない場合も、オブジェクトの前にスペースを入れます。

stdoutを使用するときは、オブジェクトを自分自身で(たとえば "str"を呼び出すことによって)文字列に変換する必要があり、改行文字はありません。

そう

print 99

以下と同等です。

import sys
sys.stdout.write(str(99) + '\n')
129
dogbane

私の質問は、sys.stdout.write()printよりも望ましい状況があるかどうかです。

先日スクリプトの開発を終えた後、私はそれをunixサーバーにアップロードしました。私のデバッグメッセージはすべてprintステートメントを使用しており、これらのしないはサーバーログに表示されます。

これはあなたが代わりにsys.stdout.writeを必要とするかもしれないケースです。

36
LiamSullivan

これは、 Pythonの学習 Mark Lutzによる、あなたの質問に取り組む本に基づいたサンプルコードです。

import sys
temp = sys.stdout                 # store original stdout object for later
sys.stdout = open('log.txt', 'w') # redirect all prints to this log file
print("testing123")               # nothing appears at interactive Prompt
print("another line")             # again nothing appears. it's written to log file instead
sys.stdout.close()                # ordinary file object
sys.stdout = temp                 # restore print commands to interactive Prompt
print("back to normal")           # this shows up in the interactive Prompt

テキストエディタでlog.txtを開くと、次のことがわかります。

testing123
another line
33
Will Townes

印刷の代わりにsys.stdoutが必要な状況が少なくとも1つあります。

次の行に行かずに行を上書きしたい場合、例えば プログレスバーやステータスメッセージを描画しているとき は、次のようにループする必要があります。

Note carriage return-> "\rMy Status Message: %s" % progress

そしてprintは改行を追加するので、あなたはsys.stdoutを使うのが得策です。

9
Carlos

私の質問は、sys.stdout.write()printよりも望ましい状況があるかどうかです。

ファイルと標準出力の両方に書き込むことができるコマンドラインアプリケーションを書いているなら、それは便利です。次のようなことができます。

def myfunc(outfile=None):
    if outfile is None:
        out = sys.stdout
    else:
        out = open(outfile, 'w')
    try:
        # do some stuff
        out.write(mytext + '\n')
        # ...
    finally:
        if outfile is not None:
            out.close()

それはあなたがwith open(outfile, 'w') as out:パターンを使うことができないことを意味しますが、時にはそれは価値があります。

8
Hamish Downer

2.xでは、printステートメントはユーザーが指定したものを前処理し、それを途中でストリングに変換し、分離文字と改行を処理し、ファイルへのリダイレクトを許可します。 3.xはそれを関数に変えますが、それでも同じ責任を持ちます。

sys.stdoutは、その行に沿って文字列または何かを取るための書き込みメソッドを持つファイルまたはファイルライクです。

Sys.stdout.write()が印刷に適している状況はありますか?

マルチスレッドの状況では、stdoutはprintよりもうまく機能することがわかりました。印刷する行を格納するためにキュー(FIFO)を使用し、印刷Qが空になるまで印刷行の前にすべてのスレッドを保持します。それでも、printを使用すると、デバッグI/Oの最後の\ nを失うことがあります(wing pro IDEを使用)。

文字列に\ nを指定してstd.outを使用すると、デバッグI/Oが正しくフォーマットされ、\ nが正しく表示されます。

1
David Poundall

Sys.stdout.write()が印刷に適している状況はありますか?

たとえば、引数として数値を渡すと星をピラミッド形式で印刷する小さな関数を作成していますが、 end = "" を使用して別の行に印刷することもできます。これを機能させるには、 sys.stdout.write print と組み合わせて使用​​します。これを詳しく説明すると、 stdout.write は同じ行に出力します。as print は常にその内容を別の行に出力します。

import sys

def printstars(count):

    if count >= 1:
        i = 1
        while (i <= count):
            x=0
            while(x<i):
                sys.stdout.write('*')
                x = x+1
            print('')
            i=i+1

printstars(5)
1
Sree

動的印刷が有用である場合、例えば長いプロセスで情報を提供することが好ましいです。

import time, sys
Iterations = 555
for k in range(Iterations+1):
    # some code to execute here ...
    percentage = k / Iterations
    time_msg = "\rRunning Progress at {0:.2%} ".format(percentage)
    sys.stdout.write(time_msg)
    sys.stdout.flush()
    time.sleep(0.01)
1
Hamidreza

Python 3では、sys.stdout.writeの上にprintを使う正当な理由がありますが、この理由は代わりにsys.stdout.writeを使う理由に変えることもできます。

この理由は、printがPython 3の関数になったからです。これをオーバーライドすることができます。そのため、単純なスクリプトのどこでもprintを使用して、それらのprintステートメントを代わりにstderrに書き込む必要があると判断できます。 print関数を定義し直すことができるようになりました。ビルトインモジュールを使用してprint関数を変更することで、print関数をグローバルに変更することもできます。もちろんfile.writeを使ってどのファイルであるかを指定することができますが、上書き印刷では行区切り文字、または引数区切り文字を再定義することもできます。

反対の方法はあります。 stdoutに書き込むことを確実にしているかもしれませんが、printを他のものに変更するつもりであることを知っていれば、sys.stdout.writeを使用し、printをエラーログまたはその他に使用することもできます。

だから、あなたが使うものは、あなたがそれをどのように使うつもりであるかにかかっている。 printはより柔軟ですが、それを使う理由と使わない理由があります。私はまだ代わりに柔軟性を選び、印刷を選びます。代わりにprintを使用するもう1つの理由は、親しみやすさです。もっと多くの人があなたが印刷で意味するものになり、sys.stdout.writeをあまり知らないようになります。

1
Hielke Walinga
>>> sys.stdout.write(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: expected a string or other character buffer object
>>> sys.stdout.write("a")
a>>> sys.stdout.write("a") ; print(1)
a1

上記の例を観察します。

  1. sys.stdout.writeは非文字列オブジェクトを書き込みませんが、printは書き込みます

  2. sys.stdout.writeは新しいラインシンボルを最後に追加しませんが、printは追加します

深く潜ると、

sys.stdoutは、print()の出力に使用できるファイルオブジェクトです

print()のファイル引数が指定されていない場合、sys.stdoutが使用されます

0
GraceMeng