การใช้เมธอด sys.stdout.flush ()


คำตอบ:


173

การออกมาตรฐานของงูใหญ่ถูกบัฟเฟอร์ (หมายถึงมันรวบรวมข้อมูลบางส่วน "เขียน" ไปยังมาตรฐานออกก่อนที่จะเขียนลงในเทอร์มินัล) การเรียกใช้sys.stdout.flush()บังคับให้ "ล้างข้อมูล" บัฟเฟอร์หมายความว่ามันจะเขียนทุกอย่างในบัฟเฟอร์ไปยังเทอร์มินัลแม้ว่าโดยปกติจะรอก่อนที่จะทำเช่นนั้น

ต่อไปนี้เป็นข้อมูลที่ดีเกี่ยวกับ (un) I / O ที่ถูกบัฟเฟอร์และทำไมจึงมีประโยชน์:
http://en.wikipedia.org/wiki/Data_buffer
Buffered เทียบกับ unbuffered IO


@Ciastopiekarz เราสามารถทำอะไรได้บ้างเพื่อให้บัฟเฟอร์ flushed บน windows?
helplessKirk

@Ciastopiekarz คุณคิดยังไง? ถ้าฉันใช้สคริปต์ Python ของ Andrew Clark และแทนที่บรรทัดการพิมพ์ด้วยsys.stdout.write("%d" % i)ดังนั้นฉันต้องยกเลิกการคอมเม้นต์sys.stdout.flush()เพื่อรับบัฟเฟอร์เพื่อแสดงขณะที่สคริปต์กำลังดำเนินการ
เบคอน Bits

119

พิจารณาสคริปต์ Python แบบง่าย ๆ ดังต่อไปนี้:

import time
import sys

for i in range(5):
    print(i),
    #sys.stdout.flush()
    time.sleep(1)

นี้ถูกออกแบบมาเพื่อพิมพ์จำนวนหนึ่งทุกวินาทีห้าวินาที แต่ถ้าคุณใช้มันเป็นอยู่ในปัจจุบัน (ขึ้นอยู่กับระบบสะเทินเริ่มต้นของคุณ) คุณอาจไม่เห็นผลใด ๆ จนกว่าจะเสร็จสิ้นการสคริปต์แล้วทั้งหมดในครั้งเดียวที่คุณจะเห็น0 1 2 3 4พิมพ์ ไปที่หน้าจอ

นี่เป็นเพราะเอาต์พุตกำลังถูกบัฟเฟอร์และถ้าคุณไม่ล้างข้อมูลsys.stdoutหลังจากนั้นprintคุณจะไม่เห็นผลลัพธ์ทันที ลบความคิดเห็นออกจากsys.stdout.flush()บรรทัดเพื่อดูความแตกต่าง


48
ใน Python 3.x ควรพิมพ์ 'print i' ด้วย print (i, end = '') เนื่องจาก print () ใน Python 3 มี prefix เริ่มต้นสิ้นสุด = '\ n' ซึ่งจะแจ้งให้คอนโซลล้างข้อมูล
ofer.sheffer

5
ฉันเพิ่งสับสนเมื่อฉันลบเครื่องหมายจุลภาคมันทำงานได้ดีตามที่คาดไว้ มีตรรกะบัฟเฟอร์ใด ๆ สำหรับบรรทัดใหม่หรือไม่?
นิล Lulla

7

ตามความเข้าใจของฉันเมื่อใดก็ตามที่เราดำเนินการเอาต์พุตคำสั่งพิมพ์จะถูกเขียนลงในบัฟเฟอร์ และเราจะเห็นผลลัพธ์บนหน้าจอเมื่อบัฟเฟอร์ถูกฟลัช (เคลียร์) โดยค่าเริ่มต้นบัฟเฟอร์จะถูกล้างเมื่อออกจากโปรแกรม แต่เราสามารถล้าง BUFFER ด้วยตนเองโดยใช้คำสั่ง "sys.stdout.flush ()" ในโปรแกรม ในบัฟเฟอร์รหัสด้านล่างจะถูกล้างออกเมื่อค่าของฉันถึง 5

คุณสามารถเข้าใจได้โดยดำเนินการรหัสด้านล่าง

chiru@online:~$ cat flush.py
import time
import sys

for i in range(10):
    print i
    if i == 5:
        print "Flushing buffer"
        sys.stdout.flush()
    time.sleep(1)

for i in range(10):
    print i,
    if i == 5:
        print "Flushing buffer"
        sys.stdout.flush()
chiru@online:~$ python flush.py 
0 1 2 3 4 5 Flushing buffer
6 7 8 9 0 1 2 3 4 5 Flushing buffer
6 7 8 9

ไม่มีเครื่องหมายจุลภาคหลังจากprint iรับเอาต์พุตของคุณ
SwimBikeRun


1

ตามความเข้าใจของฉัน sys.stdout.flush () ผลักดันข้อมูลทั้งหมดที่ถูกบัฟเฟอร์ไปยังจุดนั้นไปยังวัตถุไฟล์ ในขณะที่ใช้ stdout ข้อมูลจะถูกเก็บไว้ในหน่วยความจำบัฟเฟอร์ (บางครั้งหรือจนกว่าหน่วยความจำจะเต็ม) ก่อนที่จะถูกเขียนลงในเทอร์มินัล การใช้ flush () บังคับให้ล้างบัฟเฟอร์และเขียนไปยังเทอร์มินัลก่อนบัฟเฟอร์มีพื้นที่ว่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.