Python 3でバイナリデータをstdoutに書き込む方法は?


103

python 2.xでこれを行うことができます:

import sys, array
a = array.array('B', range(100))
a.tofile(sys.stdout)

しかし今、私はTypeError: can't write bytes to text stream。使用すべき秘密のエンコーディングはありますか?


4
これは、Python 2.6+および3.xで動作します答えを見つけるために多くの方が良いだろう
ソリン

2
os.writePy2とPy3の両方で動作します。
David Wolever 2014

回答:


169

より良い方法:

import sys
sys.stdout.buffer.write(b"some binary data")

4
を使用sys.stdout.bufferするとshutil.copyfileobj、ソースファイルオブジェクトが文字列ではなくバイトを与える場合でも、使用するようなことができます。+1
csl 2015年

1
これを使用するプログラムはIDLE 3でテストすることができません:AttributeError: 'PseudoOutputFile' object has no attribute 'buffer'
ダミアンYerrick

4
IDLEの@DamianYerrick(少なくともWindowsでは)pythonw.exeはIDLEを実行します。つまり、stdoutはありません。tkinterでエミュレートされます。物理的にバイトを処理できません。この場合、IDLEを使用する代わりに.decode('UTF-8', errors='replace')、ストリング、または実行python3 -I <filename>してREPLを取得します。
Artyer

stderrと一緒に使用する場合、書き込み時に書き込みの順序を混乱させprint(file=sys.stderr)ます。
コタウスカス

15
import os
os.write(1, a.tostring())

または、os.write(sys.stdout.fileno(), …)それが1あなたより読みやすい場合。


ありがとう、うまくいきました。少しハックっぽい感じがしますが、それはそれほど一般的なことではないと思います。
Ivan Baldin、2009年

6
問題os.writeは、すべてが書き込まれることを保証しないため、戻り値を確認する必要があることです。
mic_e

10

これを行う慣用的な方法は、Python 3でのみ利用可能です。

with os.fdopen(sys.stdout.fileno(), "wb", closefd=False) as stdout:
    stdout.write(b"my bytes object")
    stdout.flush()

良い点は、Pythonで誰もが慣れている通常のファイルオブジェクトインターフェイスを使用することです。

ブロックを終了するときにclosefd=False閉じないように設定していることに注意してください。そうしないと、プログラムはstdoutに出力できなくなります。ただし、他の種類のファイル記述子の場合は、その部分をスキップできます。sys.stdoutwith


なぜフラッシュするの?Pythonにstdoutをフラッシュするタイミングを決定させた方がいいのではないですか?
マーティン

0

python3でエンコーディングを指定したい場合でも、次のようにbytesコマンドを使用できます。

import os
os.write(1,bytes('Your string to Stdout','UTF-8'))

ここで、1はstdoutの対応する通常の番号です-> sys.stdout.fileno()

それ以外の場合、エンコーディングを気にしない場合は、次のように使用します。

import sys
sys.stdout.write("Your string to Stdout\n")

エンコーディングなしでos.writeを使用したい場合は、以下を使用してみてください:

import os
os.write(1,b"Your string to Stdout\n")

1
を使用os.write(sys.stdout.fileno(), some_bytes)するプログラムはIDLEでは機能しません。io.UnsupportedOperation: fileno
Damian Yerrick

@DamianYerrick:あなたは正しいです... IDLEはとにかくそのような何かをテストするために使用されるべきではありません。まもなく:IDLE(私はpython3.5.1シェルを持っていました)を開こうとし、単純にsysとsys.stdout.fileno()をインポートしようとします。IDLEではこれがサポートされていない操作であるため、ioエラーがスローされます:-)常に重要ですどの環境で作業しているのかを覚えて、可能なことを試してみてください;)これでクエリが明確になることを願っています:-)良い週末を。
Marco smdm 2017年

実際のバイナリデータをに書き込む方法の1つstdoutである最後の方法のみを説明します。
コタウカス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.