Jujur saya ingin tahu untuk keduanya, meskipun saya tidak punya pengalaman dengan Python 3. Diperbarui pertanyaannya.
Johanna Larsson
17
@ S.Lott: menanyakan perbedaan mendasar antara sys.stdout.write()dan print(dan / atau mengapa Python memiliki keduanya) adalah pertanyaan yang sangat masuk akal dan tidak perlu contoh. OP tidak mengatakan sintaks perintah membingungkan.
smci
Jawaban:
294
printhanyalah pembungkus tipis yang memformat input (dapat dimodifikasi, tetapi secara default dengan spasi antara args dan baris baru di akhir) dan memanggil fungsi tulis dari objek yang diberikan. Secara default objek ini sys.stdout, tetapi Anda dapat mengirimkan file menggunakan formulir "chevron". Sebagai contoh:
Dalam Python 2.6+, printmasih merupakan pernyataan, tetapi dapat digunakan sebagai fungsi dengan
from __future__ import print_function
Pembaruan: Bakuriu berkomentar untuk menunjukkan bahwa ada perbedaan kecil antara fungsi cetak dan pernyataan cetak (dan lebih umum antara fungsi dan pernyataan).
Jika terjadi kesalahan saat mengevaluasi argumen:
print"something",1/0,"other"#prints only something because 1/0 raise an Exceptionprint("something",1/0,"other")#doesn't print anything. The function is not called
Perlu juga dicatat bahwa printjuga menambahkan baris baru ke apa pun yang Anda tulis yang tidak terjadi sys.stdout.write.
Michael Mior
5
Juga sys.stdout.writelebih universal jika Anda perlu menulis kode versi ganda (mis. Kode yang bekerja secara bersamaan dengan Python 2.x dan juga Python 3.x).
andreb
3
@MichaelMior Anda dapat menekan baris baru yang printditambahkan dengan tanda koma:print "this",; print "on the same line as this"
drevicko
1
@ bjd2385 Ini >>bukan operator rshift di sini tetapi bentuk "chevron" spesifik dari printpernyataan. Lihat docs.python.org/2/reference/…
luc
5
sys.stdout.write()juga buffer input dan mungkin tidak segera menyiram input ke fd. untuk memastikan bahwa ia berperilaku seperti fungsi cetak, Anda harus menambahkan: sys.stdout.flush()
kerbelp
151
printpertama-tama mengonversi objek ke string (jika belum menjadi string). Ini juga akan menempatkan spasi di depan objek jika itu bukan awal dari sebuah baris dan karakter baris baru di akhir.
Ketika menggunakan stdout , Anda perlu mengonversi objek ke string sendiri (dengan memanggil "str", misalnya) dan tidak ada karakter baris baru.
+1 untuk menyebutkan karakter baris baru! Inilah perbedaan utama antara printdan .write(), saya katakan.
Eric O Lebigot
9
CATATAN: printdapat dibuat untuk menghilangkan baris baru. Dalam Python 2.x, beri koma di akhir, dan karakter spasi akan ditampilkan, tetapi tidak ada baris baru. Misalnya print 99,Dalam Python 3, print(..., end='')akan menghindari penambahan baris baru (dan juga menghindari penambahan ruang, kecuali jika Anda melakukannya end=' '.
ToolmakerSteve
40
@ EOL Betapa lucunya itu, bahwa seseorang bernama EOL membuat komentar tentang '\ n' ... Itu membuat saya tertawa. Saya tidak punya kehidupan. Bunuh aku.
Depado
2
itu TIDAK benar, printoperasi berperilaku sedikit berbeda dalam penangan sinyal di python2.X, yaitu cetak tidak dapat diganti dengan sys.stdout dalam contoh: stackoverflow.com/questions/10777610/…
ddzialak
41
Pertanyaan saya adalah apakah ada situasi yang
sys.stdout.write()lebih disukai
print
Setelah selesai mengembangkan skrip beberapa hari yang lalu, saya mengunggahnya ke server unix. Semua pesan debug saya menggunakan printpernyataan, dan ini tidak muncul pada log server.
Ini adalah kasus di mana Anda mungkin membutuhkannya sys.stdout.write.
Hah? Apakah Anda yakin ini perbedaan antara print()dan sys.stdout.write(), yang bertentangan dengan perbedaan antara stdoutdan stderr? Untuk debugging, Anda harus menggunakan loggingmodul, yang mencetak pesan stderr.
ostrokach
1
Ya Hal yang sama berlaku dengan menggunakan nohupdan mengarahkan ulang ke .outfile.
conner.xyz
1
penggunaan sys.stdout.flush () akan membantu.
suprit chaudhary
Jika Anda menggunakan nohup, secara default semua tulisan ke stdoutdan stderrakan diarahkan kembali ke nohup.out, mengabaikan apakah Anda menggunakan printatau stdout.write.
Zheng Liu
40
Berikut ini beberapa contoh kode berdasarkan buku Learning Python oleh Mark Lutz yang menjawab pertanyaan Anda:
import sys
temp = sys.stdout # store original stdout object for later
sys.stdout = open('log.txt','w')# redirect all prints to this log fileprint("testing123")# nothing appears at interactive promptprint("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 promptprint("back to normal")# this shows up in the interactive prompt
Membuka log.txt dalam editor teks akan mengungkapkan hal berikut:
Apakah ada cara agar saya dapat mencetak ke layar serta menulis ke file?
Devesh Saini
5
@DeveshSaini: Ya, timpa saja sys.stdout dengan kelas proxy yang memiliki setidaknya fungsi write () dan flush (). Saya menulis cuplikan contoh di sini .
ponycat
14
Setidaknya ada satu situasi di mana Anda ingin sys.stdoutalih-alih mencetak.
Saat Anda ingin menimpa baris tanpa pergi ke baris berikutnya, misalnya saat menggambar bilah kemajuan atau pesan status , Anda perlu mengulang sesuatu seperti
Note carriage return->"\rMy Status Message: %s"% progress
Dan karena cetak menambah baris baru, Anda lebih baik menggunakan sys.stdout.
Jika cetak menambahkan baris baru mengapa tidak hanya mencetak ('message', end = '')?
Apoorv Patne
8
Pertanyaan saya adalah apakah ada situasi yang sys.stdout.write()lebih disukaiprint
Jika Anda sedang menulis aplikasi baris perintah yang dapat menulis ke kedua file dan stdout maka itu berguna. Anda dapat melakukan hal-hal seperti:
def myfunc(outfile=None):if outfile isNone:
out = sys.stdout
else:
out = open(outfile,'w')try:# do some stuff
out.write(mytext +'\n')# ...finally:if outfile isnotNone:
out.close()
Itu berarti Anda tidak dapat menggunakan with open(outfile, 'w') as out:polanya, tetapi terkadang itu sepadan.
Sebenarnya, Anda dapat menggunakan with- def process(output): # .../ if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)(menambahkan baris baru jika perlu tentunya). Ini jelas tidak terlalu bersih, itu sudah pasti.
Dana Gugatan Monica
4
Dalam 2.x, the print pernyataan memproses ulang apa yang Anda berikan, mengubahnya menjadi string di sepanjang jalan, menangani pemisah dan baris baru, dan memungkinkan pengalihan ke file. 3.x mengubahnya menjadi fungsi, tetapi masih memiliki tanggung jawab yang sama.
sys.stdout adalah file atau file-seperti yang memiliki metode untuk menulis kepadanya yang mengambil string atau sesuatu di sepanjang baris itu.
lebih disukai ketika pencetakan dinamis berguna, misalnya, untuk memberikan informasi dalam proses yang panjang:
import time, sys
Iterations=555for 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)
cetak (time_msg, end = '') sebagai gantinya sys.stdout.write (time_msg) sys.stdout.flush () juga berfungsi
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
Perhatikan contoh di atas:
sys.stdout.writetidak akan menulis objek non-string, tetapi printakan
sys.stdout.writetidak akan menambahkan simbol baris baru pada akhirnya, tetapi printakan
Jika kita menyelam dalam-dalam,
sys.stdout adalah objek file yang dapat digunakan untuk output dari print ()
jika argumen file print()tidak ditentukan, sys.stdoutakan digunakan
Apakah ada situasi di mana sys.stdout.write () lebih baik dicetak?
Misalnya saya sedang mengerjakan fungsi kecil yang mencetak bintang dalam format piramida setelah melewati angka sebagai argumen, meskipun Anda dapat melakukannya menggunakan end = "" untuk mencetak dalam baris terpisah, saya menggunakan sys.stdout.write dalam koordinasi dengan cetak untuk membuat ini berfungsi. Untuk menguraikan stdout.write ini mencetak di baris yang sama di mana sebagai cetak selalu mencetak isinya dalam baris yang terpisah.
import sys
def printstars(count):if count >=1:
i =1while(i <= count):
x=0while(x<i):
sys.stdout.write('*')
x = x+1print('')
i=i+1
printstars(5)
Apakah ada situasi di mana sys.stdout.write () lebih baik dicetak?
Saya telah menemukan bahwa stdout berfungsi lebih baik daripada mencetak dalam situasi multithreading. Saya menggunakan Antrian (FIFO) untuk menyimpan garis untuk dicetak dan saya memegang semua utas sebelum garis cetak sampai Q cetak saya kosong. Meski begitu, menggunakan print saya terkadang kehilangan final \ n pada debug I / O (menggunakan wing pro IDE).
Ketika saya menggunakan std.out dengan \ n dalam string, debug I / O format dengan benar dan \ n's ditampilkan secara akurat.
Apakah Anda tahu alasan mengapa stdout harus bekerja lebih baik daripada mencetak dalam hal ini, atau ini anekdotal? Bisakah Anda memberikan contoh kerja minimal di mana ini terjadi?
user2653663
Pemikiran saya adalah stdout bekerja pada level yang lebih rendah daripada print. Saya benar-benar mengalami korupsi thread karena dua rutinitas cetak berjuang untuk memberi makan melalui stdout. Menulis ke stdout satu dari setiap utas menghapus korupsi untuk saya.
Di Python 3 ada alasan yang sah untuk menggunakan print over sys.stdout.write, tetapi alasan ini juga bisa dijadikan alasan untuk menggunakannya sys.stdout.write.
Alasannya adalah, sekarang cetak adalah fungsi dengan Python 3, Anda dapat menimpanya. Jadi, Anda dapat menggunakan cetak di mana-mana dalam skrip sederhana dan memutuskan pernyataan cetak itu perlu ditulis stderr. Anda sekarang dapat mendefinisikan ulang fungsi cetak, Anda bahkan dapat mengubah fungsi cetak global dengan mengubahnya menggunakan modul bawaan. Tentu saja denganfile.write Anda dapat menentukan file apa, tetapi dengan mencetak overwriting Anda juga dapat mendefinisikan ulang pemisah baris, atau pemisah argumen.
Sebaliknya adalah. Mungkin Anda benar-benar yakin untuk menulis surat stdout, tetapi juga tahu Anda akan mengubah cetakan menjadi sesuatu yang lain, Anda dapat memutuskan untuk menggunakannyasys.stdout.write , dan menggunakan cetak untuk log kesalahan atau sesuatu yang lain.
Jadi, apa yang Anda gunakan tergantung pada bagaimana Anda bermaksud menggunakannya. printlebih fleksibel, tetapi itu bisa menjadi alasan untuk menggunakan dan tidak menggunakannya. Saya masih akan memilih fleksibilitas, dan memilih cetak. Alasan lain untuk menggunakan printgantinya adalah keakraban. Semakin banyak orang sekarang akan apa yang Anda maksud dengan cetak dan kurang tahu sys.stdout.write.
Salah satu perbedaannya adalah sebagai berikut, ketika mencoba mencetak byte ke tampilan heksadesimalnya. Sebagai contoh, kita tahu bahwa nilai desimal 255adalah 0xFFdalam penampilan heksadesimal:
val ='{:02x}'.format(255)
sys.stdout.write(val)# prints ff2print(val)# prints ff
Ini bukan tentang ini. Itu hanya akan terjadi di shell interaktif dan karena ... write()tidak menambah \ndan mengembalikan (dan menampilkan shell interaktif) nilai kembali fungsi (jumlah karakter yang ditulis), representasi heksadesimal atau konten lain yang ditampilkan tidak material.
Ondrej K.
0
Dalam python 2 jika Anda perlu melewati fungsi maka Anda dapat menetapkan os.sys.stdout.write ke variabel, Anda tidak dapat melakukan ini (di repl) dengan cetak.
>import os
>>> cmd=os.sys.stdout.write
>>> cmd('hello')
hello>>>
Itu bekerja seperti yang diharapkan.
>>> cmd=printFile"<stdin>", line 1
cmd=print^SyntaxError: invalid syntax
Perbedaan antara printdan sys.stdout.writeuntuk menunjukkan dalam Python 3, juga nilai yang dikembalikan ketika dieksekusi di terminal. Dalam Python 3 sys.stdout.writemengembalikan panjang string sedangkan printmengembalikan sajaNone .
Jadi misalnya menjalankan kode berikut secara interaktif di terminal akan mencetak string yang diikuti oleh lenght, karena lenght dikembalikan dan dihasilkan ketika dijalankan secara interaktif:
sys.stdout.write()
danprint
(dan / atau mengapa Python memiliki keduanya) adalah pertanyaan yang sangat masuk akal dan tidak perlu contoh. OP tidak mengatakan sintaks perintah membingungkan.Jawaban:
print
hanyalah pembungkus tipis yang memformat input (dapat dimodifikasi, tetapi secara default dengan spasi antara args dan baris baru di akhir) dan memanggil fungsi tulis dari objek yang diberikan. Secara default objek inisys.stdout
, tetapi Anda dapat mengirimkan file menggunakan formulir "chevron". Sebagai contoh:Lihat: https://docs.python.org/2/reference/simple_stmts.html?highlight=print#the-print-statement
Dalam Python 3.x,
print
menjadi fungsi, tetapi masih mungkin untuk melewatkan sesuatu selainsys.stdout
berkatfile
argumennya.Lihat https://docs.python.org/3/library/functions.html#print
Dalam Python 2.6+,
print
masih merupakan pernyataan, tetapi dapat digunakan sebagai fungsi denganPembaruan: Bakuriu berkomentar untuk menunjukkan bahwa ada perbedaan kecil antara fungsi cetak dan pernyataan cetak (dan lebih umum antara fungsi dan pernyataan).
Jika terjadi kesalahan saat mengevaluasi argumen:
sumber
print
juga menambahkan baris baru ke apa pun yang Anda tulis yang tidak terjadisys.stdout.write
.sys.stdout.write
lebih universal jika Anda perlu menulis kode versi ganda (mis. Kode yang bekerja secara bersamaan dengan Python 2.x dan juga Python 3.x).print
ditambahkan dengan tanda koma:print "this",; print "on the same line as this"
>>
bukan operator rshift di sini tetapi bentuk "chevron" spesifik dariprint
pernyataan. Lihat docs.python.org/2/reference/…sys.stdout.write()
juga buffer input dan mungkin tidak segera menyiram input ke fd. untuk memastikan bahwa ia berperilaku seperti fungsi cetak, Anda harus menambahkan:sys.stdout.flush()
print
pertama-tama mengonversi objek ke string (jika belum menjadi string). Ini juga akan menempatkan spasi di depan objek jika itu bukan awal dari sebuah baris dan karakter baris baru di akhir.Ketika menggunakan
stdout
, Anda perlu mengonversi objek ke string sendiri (dengan memanggil "str", misalnya) dan tidak ada karakter baris baru.Begitu
setara dengan:
sumber
print
dan.write()
, saya katakan.print
dapat dibuat untuk menghilangkan baris baru. Dalam Python 2.x, beri koma di akhir, dan karakter spasi akan ditampilkan, tetapi tidak ada baris baru. Misalnyaprint 99,
Dalam Python 3,print(..., end='')
akan menghindari penambahan baris baru (dan juga menghindari penambahan ruang, kecuali jika Anda melakukannyaend=' '
.print
operasi berperilaku sedikit berbeda dalam penangan sinyal di python2.X, yaitu cetak tidak dapat diganti dengan sys.stdout dalam contoh: stackoverflow.com/questions/10777610/…Setelah selesai mengembangkan skrip beberapa hari yang lalu, saya mengunggahnya ke server unix. Semua pesan debug saya menggunakan
print
pernyataan, dan ini tidak muncul pada log server.Ini adalah kasus di mana Anda mungkin membutuhkannya
sys.stdout.write
.sumber
print()
dansys.stdout.write()
, yang bertentangan dengan perbedaan antarastdout
danstderr
? Untuk debugging, Anda harus menggunakanlogging
modul, yang mencetak pesanstderr
.nohup
dan mengarahkan ulang ke.out
file.nohup
, secara default semua tulisan kestdout
danstderr
akan diarahkan kembali kenohup.out
, mengabaikan apakah Anda menggunakanprint
ataustdout.write
.Berikut ini beberapa contoh kode berdasarkan buku Learning Python oleh Mark Lutz yang menjawab pertanyaan Anda:
Membuka log.txt dalam editor teks akan mengungkapkan hal berikut:
sumber
Setidaknya ada satu situasi di mana Anda ingin
sys.stdout
alih-alih mencetak.Saat Anda ingin menimpa baris tanpa pergi ke baris berikutnya, misalnya saat menggambar bilah kemajuan atau pesan status , Anda perlu mengulang sesuatu seperti
Dan karena cetak menambah baris baru, Anda lebih baik menggunakan
sys.stdout
.sumber
Jika Anda sedang menulis aplikasi baris perintah yang dapat menulis ke kedua file dan stdout maka itu berguna. Anda dapat melakukan hal-hal seperti:
Itu berarti Anda tidak dapat menggunakan
with open(outfile, 'w') as out:
polanya, tetapi terkadang itu sepadan.sumber
with
-def process(output): # ...
/if outfile is None: process(sys.stdout) else: with open(outfile, 'w') as out: process(out)
(menambahkan baris baru jika perlu tentunya). Ini jelas tidak terlalu bersih, itu sudah pasti.Dalam 2.x, the
print
pernyataan memproses ulang apa yang Anda berikan, mengubahnya menjadi string di sepanjang jalan, menangani pemisah dan baris baru, dan memungkinkan pengalihan ke file. 3.x mengubahnya menjadi fungsi, tetapi masih memiliki tanggung jawab yang sama.sys.stdout
adalah file atau file-seperti yang memiliki metode untuk menulis kepadanya yang mengambil string atau sesuatu di sepanjang baris itu.sumber
lebih disukai ketika pencetakan dinamis berguna, misalnya, untuk memberikan informasi dalam proses yang panjang:
sumber
Perhatikan contoh di atas:
sys.stdout.write
tidak akan menulis objek non-string, tetapiprint
akansys.stdout.write
tidak akan menambahkan simbol baris baru pada akhirnya, tetapiprint
akanJika kita menyelam dalam-dalam,
sys.stdout
adalah objek file yang dapat digunakan untuk output dari print ()jika argumen file
print()
tidak ditentukan,sys.stdout
akan digunakansumber
Misalnya saya sedang mengerjakan fungsi kecil yang mencetak bintang dalam format piramida setelah melewati angka sebagai argumen, meskipun Anda dapat melakukannya menggunakan end = "" untuk mencetak dalam baris terpisah, saya menggunakan sys.stdout.write dalam koordinasi dengan cetak untuk membuat ini berfungsi. Untuk menguraikan stdout.write ini mencetak di baris yang sama di mana sebagai cetak selalu mencetak isinya dalam baris yang terpisah.
sumber
Saya telah menemukan bahwa stdout berfungsi lebih baik daripada mencetak dalam situasi multithreading. Saya menggunakan Antrian (FIFO) untuk menyimpan garis untuk dicetak dan saya memegang semua utas sebelum garis cetak sampai Q cetak saya kosong. Meski begitu, menggunakan print saya terkadang kehilangan final \ n pada debug I / O (menggunakan wing pro IDE).
Ketika saya menggunakan std.out dengan \ n dalam string, debug I / O format dengan benar dan \ n's ditampilkan secara akurat.
sumber
Di Python 3 ada alasan yang sah untuk menggunakan print over
sys.stdout.write
, tetapi alasan ini juga bisa dijadikan alasan untuk menggunakannyasys.stdout.write
.Alasannya adalah, sekarang cetak adalah fungsi dengan Python 3, Anda dapat menimpanya. Jadi, Anda dapat menggunakan cetak di mana-mana dalam skrip sederhana dan memutuskan pernyataan cetak itu perlu ditulis
stderr
. Anda sekarang dapat mendefinisikan ulang fungsi cetak, Anda bahkan dapat mengubah fungsi cetak global dengan mengubahnya menggunakan modul bawaan. Tentu saja denganfile.write
Anda dapat menentukan file apa, tetapi dengan mencetak overwriting Anda juga dapat mendefinisikan ulang pemisah baris, atau pemisah argumen.Sebaliknya adalah. Mungkin Anda benar-benar yakin untuk menulis surat
stdout
, tetapi juga tahu Anda akan mengubah cetakan menjadi sesuatu yang lain, Anda dapat memutuskan untuk menggunakannyasys.stdout.write
, dan menggunakan cetak untuk log kesalahan atau sesuatu yang lain.Jadi, apa yang Anda gunakan tergantung pada bagaimana Anda bermaksud menggunakannya.
print
lebih fleksibel, tetapi itu bisa menjadi alasan untuk menggunakan dan tidak menggunakannya. Saya masih akan memilih fleksibilitas, dan memilih cetak. Alasan lain untuk menggunakanprint
gantinya adalah keakraban. Semakin banyak orang sekarang akan apa yang Anda maksud dengan cetak dan kurang tahusys.stdout.write
.sumber
Salah satu perbedaannya adalah sebagai berikut, ketika mencoba mencetak byte ke tampilan heksadesimalnya. Sebagai contoh, kita tahu bahwa nilai desimal
255
adalah0xFF
dalam penampilan heksadesimal:sumber
write()
tidak menambah\n
dan mengembalikan (dan menampilkan shell interaktif) nilai kembali fungsi (jumlah karakter yang ditulis), representasi heksadesimal atau konten lain yang ditampilkan tidak material.Dalam python 2 jika Anda perlu melewati fungsi maka Anda dapat menetapkan os.sys.stdout.write ke variabel, Anda tidak dapat melakukan ini (di repl) dengan cetak.
Itu bekerja seperti yang diharapkan.
Itu tidak bekerja. cetak adalah fungsi ajaib.
sumber
Perbedaan antara
print
dansys.stdout.write
untuk menunjukkan dalam Python 3, juga nilai yang dikembalikan ketika dieksekusi di terminal. Dalam Python 3sys.stdout.write
mengembalikan panjang string sedangkanprint
mengembalikan sajaNone
.Jadi misalnya menjalankan kode berikut secara interaktif di terminal akan mencetak string yang diikuti oleh lenght, karena lenght dikembalikan dan dihasilkan ketika dijalankan secara interaktif:
sumber