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


376

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

例:パフォーマンスの向上、より意味のあるコード)


4
Pythonのどのバージョンですか?2.xまたは3.x?
マークバイヤーズ10/07/16

正直なところ、両方について知りたいのですが、Python 3の経験はありません。質問を更新しました。
Johanna Larsson

17
@ S.Lott:基本的な違いを尋ねるsys.stdout.write()print(および/またはPythonは両方を持っている理由)は完全に合理的な質問をし、例を必要としません。OPは、コマンド構文がわかりにくいとは言いませんでした。
smci、2015年

回答:


294

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

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関数になりますがsys.stdoutfile引数のおかげでそれ以外のものを渡すことも可能です。

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 function is not called

64
またprint、で発生しない記述に改行を追加することにも注意してくださいsys.stdout.write
マイケル・ミオール

5
また、sys.stdout.writeデュアルバージョンのコード(Python 2.xとPython 3.xで同時に動作するコードなど)を記述する必要がある場合にも、より普遍的です。
andreb

3
@MichaelMiorあなたは改行抑えることができるprint:末尾のカンマを追加print "this",; print "on the same line as this"
drevicko

1
@ bjd2385これ>>は、ここではrshift演算子ではなく、ステートメントの特定の「シェブロン」形式ですprintdocs.python.org/2/reference/…を
luc

5
sys.stdout.write()また、入力をバッファリングし、入力をすぐにfdにフラッシュしない場合があります。それは印刷機能と同じように動作し、あなたが追加する必要があることを確実にするために: sys.stdout.flush()
kerbelp

151

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

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

そう

print 99

以下と同等です。

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

32
改行文字について言及するための+1!これが主な違いであるprint.write()、私が言うと思います。
Eric O Lebigot、

9
注:print改行を省略するように作成できます。Python 2.xでは、末尾にカンマを付けると、空白文字が出力されますが、改行は出力されません。たとえばprint 99,ではPython 3、print(..., end='')改行を追加しない(ともあなたが行う場合を除き、スペースを追加しないようにしますend=' '
ToolmakerSteve

40
@EOL EOLという名前の誰かが '\ n'についてコメントしているのは面白いですね。私にはもう楽しみも何もありません。私を殺して。
Depado

2
それは、真実ではないprintpython2.Xにおけるシグナルハンドラが若干異なる動作振る舞い、すなわち印刷を例にsys.stdoutの置き換えることができません。stackoverflow.com/questions/10777610/...
ddzialak

41

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

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

これは、sys.stdout.write代わりに必要になる場合があるケースです。


8
え?あなたは、これはとの間の差である確信しているprint()sys.stdout.write()の違いとは反対に、stdoutstderr?デバッグには、loggingメッセージをに出力するモジュールを使用する必要がありますstderr
ostrokach 2016年

1
Y A。ファイルの使用nohupとリダイレクトについても同様.outです。
conner.xyz 2016年

1
sys.stdout.flush()を使用すると役立ちます。
suprit chaudhary

を使用する場合nohup、デフォルトではすべての書き込みstdoutstderrにリダイレクトされますnohup.out、あなたが使用するかどうか無視printstdout.write
鄭劉

40

Mark Lutz 著のLearning Pythonに基づいた、サンプルのコードを以下に示します。

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

画面に印刷したり、ファイルに書き込んだりする方法はありますか?
Devesh Saini 2014

5
@DeveshSaini:はい、少なくともwrite()関数とflush()関数を持つプロキシクラスでsys.stdoutを上書きします。ここにサンプルのスニペットを書きました。
ポニーキャット2014年

14

sys.stdout印刷ではなく、少なくとも1つの状況が必要です。

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

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

また、印刷により改行が追加されるため、を使用しsys.stdoutた方がよいでしょう。


2
printが新しい行を追加する場合、なぜ代わりにprint( 'message'、end = '')を実行しないのですか?
Apoorv Patne

8

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

ファイルとstdoutの両方に書き込むことができるコマンドラインアプリケーションを作成している場合は、便利です。次のようなことができます。

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:パターンを使用できないことを意味しますが、時にはそれは価値があります。


厳密に言えば、- / 使用できます(もちろん、必要に応じて改行を追加します)。確かにそれほどきれいではありませんが、それは確かです。withdef process(output): # ...if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)
モニカの訴訟に資金を

4

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

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


3

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

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)

2
print(time_msg、end = '')代わりにsys.stdout.write(time_msg)sys.stdout.flush()も機能します
rluts

2
>>> 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は、使用されます


1

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

たとえば、引数として数値を渡すとピラミッド形式で星を印刷する小さな関数に取り組んでいますが、end = ""を使用して別の行に印刷することもできますが、調整ではsys.stdout.writeを使用しました印刷この作品を作るために。このstdout.writeについて詳しく説明すると、同じ行に出力されますが、as 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

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

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

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


この場合にstdoutが印刷よりもうまく機能する理由を何か知っていますか?これは逸話ですか?これが発生する最小限の動作例を提供できますか?
user2653663 2018

私の考えでは、stdoutは印刷よりも低いレベルで機能します。2つの印刷ルーチンがstdoutを介してフィードするために戦っていたため、私は間違いなくスレッドが破損していました。各スレッドから1つstdoutに書き込むと、破損がなくなりました。
David Poundall


1

Python 3 sys.stdout.writeでは、print overを使用する正当な理由がありますが、この理由は、使用する理由にもなります。sys.stdout.write代わります。

これは、printがPython 3の関数になったため、これをオーバーライドできるためです。したがって、単純なスクリプトのどこでもprintを使用して、stderr代わりにそれらのprintステートメントで書き込む必要があると判断できます。印刷機能を再定義するだけで、組み込み関数を使用して変更することで、印刷機能をグローバルに変更することもできます。もちろんオフfile.writeファイルを指定することもできますが、印刷を上書きすることで、行セパレーターや引数セパレーターを再定義することもできます。

その逆です。多分あなたはあなたが書いたことを絶対に確信しているだけでstdoutなく、あなたがプリントを他のものに変更するつもりであることを知っているなら、sys.stdout.write、エラーログまたは何か他のもののために印刷ます。

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


1

違いの1つは、バイトを16進数の外観に印刷しようとすると、次のようになります。たとえば、の10進数値2550xFF16進数で表示されます。

val = '{:02x}'.format(255) 

sys.stdout.write(val) # prints ff2
print(val)            # prints ff

それはこれについてではありません。これは、インタラクティブシェルでのみ発生します。関数の戻り値(書き込まれた文字数)、16進数表現、またはその他の表示されているコンテンツをwrite()追加\nして返さなかったため(インタラクティブシェルの表示)、重要ではありません。
Ondrej K.

0

Python 2では、関数を渡す必要がある場合は、os.sys.stdout.writeを変数に割り当てることができます。これを(replで)printで行うことはできません。

>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>> 

それは期待どおりに動作します。

>>> cmd=print
  File "<stdin>", line 1
    cmd=print
            ^
SyntaxError: invalid syntax

それは機能しません。printは不思議な機能です。


0

Python 3で指摘されているprintとの違いはsys.stdout.write、ターミナルで実行されたときに返される値でもあります。Python 3ではsys.stdout.write、文字列の長さをprint返しますが、None

たとえば、次のコードをターミナルでインタラクティブに実行すると、文字列の後にその長さが出力されます。これは、インタラクティブに実行すると長さが返されて出力されるためです。

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