2009-05-25 20 views
53

w Pythonie 2.x mogę to zrobić:Jak pisać dane binarne w stdout w python 3?

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

Teraz jednak mogę dostać TypeError: can't write bytes to text stream. Czy jest jakieś tajne kodowanie, które powinienem użyć?

+3

Byłoby znacznie lepiej, aby znaleźć odpowiedź, która będzie pracować z Python 2.6+ i 3. x – sorin

+1

'os.write' będzie działać zarówno na Py2, jak i Py3. –

Odpowiedz

90

Lepszym sposobem:

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

Użycie 'sys.stdout.buffer' pozwala ci również na użycie' shutil.copyfileobj' nawet wtedy, gdy obiekt pliku źródłowego podaje bajty, a nie ciągi. +1 – csl

+0

Programy używające tego nie mogą być testowane w IDLE 3: 'AttributeError: 'Obiekt PseudoOutputFile' nie ma atrybutu 'buffer'' –

+0

@DamianYerrick w IDLE (przynajmniej w systemie Windows)' pythonw.exe' uruchamia IDLE, co oznacza że nie ma stdout. Jest emulowany za pomocą tkintera. Fizycznie nie może obsłużyć bajtów. W tym przypadku '.dode ('UTF-8', errors = 'replace')' twój ciąg lub uruchom 'python3-I ', aby uzyskać REPL zamiast używać IDLE. – Artyer

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

lub os.write(sys.stdout.fileno(), …) jeśli to bardziej czytelne niż 1 dla Ciebie.

+0

Dzięki, to zadziałało. Wydaje się nieco hack-owski, ale myślę, że to nie jest tak często robić. –

+4

Problem z 'os.write' polega na tym, że musisz sprawdzić wartość zwracaną, ponieważ nie gwarantuje to, że wszystko zostanie zapisane. –

0

W przypadku chcesz określić kodowanie w python3 można nadal używać bajtów polecenia jak poniżej:

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

gdzie 1 jest odpowiedni zwykły numer dla stdout -> sys.stdout.fileno()

W przeciwnym razie, jeśli nie obchodzi cię kodowanie, użyj:

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

Jeśli chcesz użyć os.write bez kodowania, a następnie spróbuj użyć poniżej:

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

Programy używające 'os.write (sys.stdout.fileno(), some_bytes)' nie będą działały w IDLE. 'io.UnsupportedOperation: fileno' –

+0

@DamianYerrick: Masz rację ... IDLE nie powinno być używane, aby przetestować coś takiego. Krótko: spróbuj otworzyć IDLE (miałem powłokę python3.5.1) i po prostu zaimportuję sys i sys.stdout.fileno() to spowoduje błąd youo, ponieważ w IDLE to nie jest obsługiwana operacja :-) To jest zawsze ważne aby pamiętać, w jakim środowisku pracujesz i próbujesz uzyskać to, co jest możliwe;) Mam nadzieję, że to wyjaśni twoje zapytanie :-) Miłego weekendu. –