171

In python 2.x I could do this:

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

Now however, I get a TypeError: can't write bytes to text stream. Is there some secret encoding that I should use?

2
  • 4
    It would be much better to find an answer that will work with Python 2.6+ and 3.x Commented Jun 14, 2010 at 17:19
  • 3
    os.write will work on both Py2 and Py3. Commented Apr 26, 2014 at 17:50

4 Answers 4

288

A better way:

import sys
sys.stdout.buffer.write(b"some binary data")
Sign up to request clarification or add additional context in comments.

8 Comments

Using sys.stdout.buffer also lets you do things like using shutil.copyfileobj even when the source file object gives bytes, and not strings. +1
Programs using this can't be tested in IDLE 3: AttributeError: 'PseudoOutputFile' object has no attribute 'buffer'
@DamianYerrick in IDLE (in Windows at least) pythonw.exe runs IDLE, which means that there is no stdout. It is emulated with tkinter. It physically can't handle bytes. In this case, .decode('UTF-8', errors='replace') your string, or run python3 -I <filename> to get a REPL instead of using IDLE.
Messes up order of writes when writing to stderr if using along with print(file=sys.stderr).
@VincentAlex sys.stdout.flush()
|
25

An idiomatic way of doing so, which is only available for Python 3, is:

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

The good part is that it uses the normal file object interface, which everybody is used to in Python.

Notice that I'm setting closefd=False to avoid closing sys.stdout when exiting the with block. Otherwise, your program wouldn't be able to print to stdout anymore. However, for other kind of file descriptors, you may want to skip that part.

8 Comments

Why do you flush? Isn't it better to let Python decide when to flush stdout?
Can't the existing channel -- such as sys.stdout -- be somehow turned into binary mode (and then back) without opening a new one on top of it?
I don't think so. BTW I flush because otherwise the fd will be closed. Maybe python would flush anyways... you can try and report.
sys.stdout.buffer is in binary mode
"Notice that I'm setting closefd=False to avoid closing sys.stdout when exiting the with block. " Is it actually valid to re-open it when it's already open, though?
|
19
import os
os.write(1, a.tostring())

or, os.write(sys.stdout.fileno(), …) if that's more readable than 1 for you.

2 Comments

Thanks, that worked. Feels a bit hack-ish but I guess it's not that common thing to do.
The problem with os.write is that you'll have to check the return value, as it doesn't guarantee that everything will be written.
3

In case you would like to specify an encoding in python3 you can still use the bytes command like below:

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

where 1 is the corresponding usual number for stdout --> sys.stdout.fileno()

Otherwise if you don't care of the encoding just use:

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

If you want to use the os.write without the encoding, then try to use the below:

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

3 Comments

Programs using os.write(sys.stdout.fileno(), some_bytes) won't work in IDLE. io.UnsupportedOperation: fileno
@DamianYerrick: You are right...the IDLE should not be used anyway to test something like that. Shortly: try to open the IDLE (I had the python3.5.1 shell) and simply import sys and sys.stdout.fileno() it will throw you io error, because in IDLE this is not supported operation :-) It is always important to remember in which environment you are working and try to get what is possible ;) Hope this clarify your query :-) Have a nice weekend.
You only mention one way of writing actual binary data to stdout, the last one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.