Python 3'te stdout'a ikili veri nasıl yazılır?


104

Python 2.x'te şunu yapabilirim:

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

Ancak şimdi bir TypeError: can't write bytes to text stream. Kullanmam gereken gizli kodlama var mı?


4
Python 2.6+ ve 3.x ile çalışacak bir cevap bulmak çok daha iyi olurdu
sorin

2
os.writehem Py2 hem de Py3 üzerinde çalışacaktır.
David Wolever

Yanıtlar:


170

En iyi yol:

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

4
Kullanımı sys.stdout.bufferda kullandığınız gibi şeyler yapalım shutil.copyfileobjdizeleri kaynak dosya nesne bayt verdiğinde bile değil. +1
csl

1
Bunu kullanan programlar IDLE 3'te test edilemez:AttributeError: 'PseudoOutputFile' object has no attribute 'buffer'
Damian Yerrick

4
IDLE'de @DamianYerrick (en azından Windows'ta) IDLE'yi pythonw.exeçalıştırır, bu da standart çıkış olmadığı anlamına gelir. Tkinter ile emüle edilmiştir. Baytları fiziksel olarak işleyemez. Bu durumda, IDLE kullanmak yerine bir REPL almak için dizeniz .decode('UTF-8', errors='replace')veya çalıştırın python3 -I <filename>.
Artyer

İle stderrbirlikte kullanılırsa , yazarken yazma sırasını bozar print(file=sys.stderr).
Kotauskas

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

veya os.write(sys.stdout.fileno(), …)bu 1sizden daha okunaklıysa .


Teşekkürler, işe yaradı. Biraz hack-ish hissediyor ama sanırım yapılacak o kadar yaygın bir şey değil.
Ivan Baldin

6
Bununla ilgili sorun os.write, her şeyin yazılacağını garanti etmediği için dönüş değerini kontrol etmeniz gerekmesidir.
mic_e

11

Bunu yapmanın sadece Python 3 için geçerli olan deyimsel bir yolu şudur:

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

İşin iyi yanı, Python'da herkesin alışkın olduğu normal dosya nesnesi arayüzünü kullanmasıdır.

Bloktan çıkarken closefd=Falsekapatmayı önlemeye ayarladığıma dikkat edin . Aksi takdirde, programınız artık stdout'a yazdıramaz. Bununla birlikte, diğer türden dosya tanımlayıcıları için bu bölümü atlamak isteyebilirsiniz.sys.stdoutwith


Neden kızarıyorsun? Python'un stdout'u ne zaman temizleyeceğine karar vermesine izin vermek daha iyi değil mi?
Martin

0

Python3'te bir kodlama belirtmek isterseniz, yine de aşağıdaki gibi bayt komutunu kullanabilirsiniz:

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

burada 1, stdout -> sys.stdout.fileno () için karşılık gelen olağan sayıdır

Aksi takdirde, kodlamayı önemsemiyorsanız sadece şunu kullanın:

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

Os.write'ı kodlama olmadan kullanmak istiyorsanız, aşağıdakileri kullanmayı deneyin:

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

1
Kullanılan programlar os.write(sys.stdout.fileno(), some_bytes)IDLE'de çalışmaz. io.UnsupportedOperation: fileno
Damian Yerrick

@DamianYerrick: Haklısın ... IDLE zaten böyle bir şeyi test etmek için kullanılmamalıdır. Kısaca: IDLE'yi açmayı deneyin (python3.5.1 kabuğuna sahiptim) ve sadece sys ve sys.stdout.fileno () 'yu içe aktarın, bu size io hatası verir, çünkü IDLE'de bu desteklenmeyen işlem :-) Bu her zaman önemlidir hangi ortamda çalıştığınızı hatırlamak ve mümkün olanı elde etmeye çalışmak;) Umarım bu sorunuzu netleştirir :-) İyi bir hafta sonu geçirin.
Marco smdm

Gerçek ikili verileri yazmanın yalnızca bir yolundan bahsediyorsunuz stdout, sonuncusu.
Kotauskas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.