अजगर में stdout करने के लिए पिछले प्रिंट को कैसे लिखना है?


113

अगर मेरे पास निम्न कोड था:

for x in range(10):
     print x

मुझे इसका आउटपुट मिलेगा

1
2
etc..

जो मैं करना चाहता हूं वह एक नई पंक्ति को प्रिंट करने के बजाय है, मैं पिछले मूल्य को बदलना चाहता हूं और उसी लाइन पर नए मूल्य के साथ इसे अधिलेखित करना चाहता हूं।



एक साइड नोट के रूप में, यह सुनिश्चित करें कि आपको वह उत्तर मिल जाए, जो पिछली लाइन को वर्तमान लाइन की तुलना में लंबे समय तक फ्लश करने में सक्षम हो ।
— फलों का

जवाबों:


119

एक तरीका यह है कि गाड़ी की वापसी ( '\r') वर्ण का उपयोग अगली पंक्ति के लिए आगे बढ़े बिना लाइन की शुरुआत में लौटने के लिए करें:

for x in range(10):
    print '{0}\r'.format(x),
print

प्रिंट स्टेटमेंट के अंत में अल्पविराम इसे अगली पंक्ति में नहीं जाने के लिए कहता है। अंतिम प्रिंट स्टेटमेंट अगली पंक्ति के लिए आगे बढ़ता है, इसलिए आपका संकेत आपके अंतिम आउटपुट को अधिलेखित नहीं करेगा।

अपडेट करें

अब जब कि पायथन 2 ईओएल है, तो पायथन 3 का उत्तर अधिक समझ में आता है। पायथन 3.5 और उससे पहले के लिए:

for x in range(10):
    print('{}\r'.format(x), end="")
print()

पायथन में 3.6 और बाद में, एफ-स्ट्रिंग्स बेहतर पढ़े:

for x in range(10):
    print(f'{x}\r', end="")
print()

यह काम करता है, लेकिन मुझे कुछ हिस्सों की समझ नहीं है ... '{0}' और
— .format

7
इसे पायथन 2.6 में पेश किया गया है और (मुझे बताया गया है) पायथन 3 में स्ट्रिंग्स को प्रारूपित करने का मानक तरीका है; %ऑपरेटर मान्य नहीं है। असल में, सभी तार अब एक प्रारूप विधि है। इस मामले में, का {0}अर्थ है "पहला तर्क format()" (गिनती 0 से शुरू होती है)।
— माइक डीमोन

एक विकल्प नहीं है अगर आपको कुछ विंडोज-केवल सॉफ्टवेयर का उपयोग करना है और वीएम को चलाने के लिए चॉप नहीं है।
— माइक डीमोन

2
और यदि आप क्रॉस-टर्मिनल बनना चाहते हैं, तो आपको re.sub(r'\$<\d+>[/*]?', '', curses.tigetstr('el') or '')उपयोगकर्ता के पास जो भी टर्मिनल है, उसके लिए सही मिटा-टू-एंड-ऑफ-द-लाइन स्ट्रिंग देगा। cursesजैसे कुछ के साथ आरंभ करने के लिए याद रखें curses.setupterm(fd=sys.stdout.fileno()), और sys.stdout.isatty()यह सुनिश्चित करने के लिए उपयोग करें कि आपका आउटपुट किसी फ़ाइल पर रीडायरेक्ट नहीं किया जा रहा है। कर्सर नियंत्रण और रंग समर्थन के साथ एक पूर्ण पायथन मॉड्यूल के लिए code.activestate.com/recipes/475116 देखें ।
— माइक डीस्मोन

1
@PhilMacKay: मैंने कोशिश की कि मेरे मैक पर अजगर: [3] में: "Thing to erase \ r", प्रिंट करें; time.sleep (1); प्रिंट "-------------- \ r", -------------- मुझे लगता है कि आपकी समस्या विंडोज है और इसकी अलग लाइन समाप्त होती है। इसे आज़माएँ: import curses; curses.setupterm(fd=sys.stdout.fileno()); print(hex(curses.tigetstr('cr')));यह लाइन के प्रारंभ में जाने के लिए वर्ण अनुक्रम के हेक्स कोड को प्रिंट करना चाहिए।
— माइक डेसिमोन

107

चूँकि मैं Google के माध्यम से यहाँ समाप्त हुआ था लेकिन मैं पायथन 3 का उपयोग कर रहा हूँ, यहाँ यह पायथन 3 में कैसे काम करेगा:

for x in range(10):
    print("Progress {:2.1%}".format(x / 10), end="\r")

संबंधित जवाब यहां: मैं प्रिंट स्टेटमेंट के बाद न्यूलाइन को कैसे दबा सकता हूं?


3
मैंने यह कोशिश की और यह ज्यादातर ठीक है। एकमात्र समस्या यह है कि उस लाइन पर पूर्व आउटपुट को मिटाया नहीं जा रहा है, उदाहरण के लिए: यदि आपका पहला लूप प्रिंट testingऔर testदूसरा पास होने के बाद भी आपका दूसरा लूप आउटपुट प्रिंट करता है testing- तो अब मैं देख रहा हूं कि @ नागासाकी
— 45

15
एक ipython नोटबुक में, मुझे करना है:print("\r", message, end="")
— ग्रैजाइटिस

1
यह महान काम करता है, यह लाइन को मिटाता नहीं है लेकिन निम्नलिखित प्रिंट में पर्याप्त व्हाट्सएप का उपयोग करने से काम होता है (हालांकि यह सुरुचिपूर्ण नहीं है)। एक टिप्पणी मैं जोड़ सकता हूं कि यह वीएस कोड के डिबग कंसोल में काम नहीं करता है, लेकिन यह टर्मिनल में काम करता है।
— फिलमकेय

31

@ माइक डीसिम्न उत्तर शायद ज्यादातर समय काम करेगा। परंतु...

for x in ['abc', 1]:
    print '{}\r'.format(x),

-> 1bc

इसका कारण यह है कि '\r'केवल लाइन की शुरुआत में वापस जाता है, लेकिन आउटपुट को साफ नहीं करता है।

संपादित करें: बेहतर समाधान (मेरे पुराने प्रस्ताव से नीचे)

यदि आपके लिए POSIX समर्थन पर्याप्त है, तो निम्नलिखित वर्तमान रेखा को साफ कर देगा और कर्सर को इसकी शुरुआत में छोड़ देगा:

print '\x1b[2K\r',

यह टर्मिनल लाइन को साफ़ करने के लिए ANSI एस्केप कोड का उपयोग करता है। अधिक जानकारी विकिपीडिया में और इस महान वार्ता में मिल सकती है ।

पुराना उत्तर

(इतना अच्छा नहीं) समाधान मुझे मिला है इस तरह दिखता है:

last_x = ''
for x in ['abc', 1]:
    print ' ' * len(str(last_x)) + '\r',
    print '{}\r'.format(x),
    last_x = x

-> 1

एक फायदा यह है कि यह खिड़कियों पर भी काम करेगा।


1
मैंने 'पुराने उत्तर' से एक फ़ंक्शन बनाया जो ठीक से काम करता है (विंडोज पर भी), मेरा जवाब देखें: stackoverflow.com/a/43952192/965332
— erb

25

इस धागे पर जाने से पहले मेरा भी यही सवाल था। मेरे लिए sys.stdout.write ने तभी काम किया जब मैं बफर को सही तरीके से फ्लश करता था

for x in range(10):
    sys.stdout.write('\r'+str(x))
    sys.stdout.flush()

फ्लशिंग के बिना, परिणाम केवल स्क्रिप्ट के अंत में मुद्रित होता है


इसके अलावा रिक्त स्थान के साथ स्ट्रिंग को भरने के लिए अच्छा विचार है जैसे stringvar.ljust(10,' ')कि चर लंबाई के साथ तार के मामले में।
— अनारफिक

@ क्रिस, डॉन एट अल। यह पायथन 2 है, अधिकांश अन्य उत्तर पायथन 3 हैं। सभी को अब पायथन 3 का उपयोग करना चाहिए; अजगर 2 2020 में जीवन का अंत कर रहा है।
— smci


9

इसे इस्तेमाल करे:

import time
while True:
    print("Hi ", end="\r")
    time.sleep(1)
    print("Bob", end="\r")
    time.sleep(1)

इसने मेरे लिए काम किया। end="\r"हिस्सा यह पिछले लाइन के ऊपर लिख कर रही है।

चेतावनी!

यदि आप प्रिंट आउट लेते हैं hi, तो प्रिंट आउट helloका उपयोग करें \r, आपको मिलेगा hilloक्योंकि पिछले दो अक्षरों में आउटपुट लिखा था। यदि आप hiरिक्त स्थान (जो यहां नहीं दिखाते हैं) के साथ प्रिंट आउट लेते हैं, तो यह आउटपुट करेगा hi। इसे ठीक करने के लिए, रिक्त स्थान का उपयोग करके प्रिंट करें \r।


1
यह मेरे लिए काम नहीं करता है। मैंने उस कोड को कॉपी किया, लेकिन मेरा आउटपुट है Hi BobHi BobHi BobHi BobHi Bob। पायथन 3.7.1
— पॉलमैग

1
लेकिन रुबिक्रेड के जवाब ने काम किया। अजीब। वे मुझे उसी विधि की तरह लगते हैं। एकमात्र अंतर जो मैं देख रहा हूं \rवह अंत के बजाय शुरुआत में है।
— पॉलमैग

7

मैं इस पेज पर किसी भी समाधान को आईपीथॉन के लिए काम नहीं कर सका , लेकिन @ माइक-डेसिमोन के समाधान पर थोड़ी भिन्नता ने काम किया: गाड़ी वापसी के साथ लाइन को समाप्त करने के बजाय, गाड़ी वापसी के साथ लाइन शुरू करें:

for x in range(10):
    print '\r{0}'.format(x),

इसके अतिरिक्त, इस दृष्टिकोण को दूसरे प्रिंट स्टेटमेंट की आवश्यकता नहीं है।


यहां तक ​​कि जो PyDev कंसोल में काम नहीं करता है, और न ही प्रिंट () के पास कोष्ठक के बाद अल्पविराम होता है।
— नौमेनन

मेरे लिए काम नहीं किया, यह सिर्फ अंतिम परिणाम (उदा: "डाउनलोड प्रगति 100%") लिखता है एक बार प्रक्रिया की बात है।
— एलेक्जेंड्रे

2
@ अलेक्सांड्रे यह आईपीथॉन या इसके उत्तराधिकारी जुपिटर में ठीक काम करता है। आपको बफर को फ्लश करने की आवश्यकता है। stackoverflow.com/questions/17343688/…
— मार्च हो

7
for x in range(10):
    time.sleep(0.5) # shows how its working
    print("\r {}".format(x), end="")

time.sleep (0.5) यह दिखाना है कि पिछले आउटपुट को कैसे मिटाया जाता है और प्रिंट संदेश के शुरू होने पर नया आउटपुट "\ r" प्रिंट किया जाता है, यह नए आउटपुट से पहले पिछले आउटपुट को मिटा देता है।



5

स्वीकार किए जाते हैं जवाब नहीं है सही । जो लाइन पहले प्रिंट की गई थी, वह वहीं रहेगी और अगर आपका दूसरा प्रिंट पूरी नई लाइन को कवर नहीं करता है, तो आप कचरा टेक्स्ट के साथ समाप्त हो जाएंगे।

समस्या को समझने के लिए इस कोड को स्क्रिप्ट के रूप में सहेजें और इसे चलाएं (या बस एक नज़र डालें):

import time

n = 100
for i in range(100):
    for j in range(100):
        print("Progress {:2.1%}".format(j / 100), end="\r")
        time.sleep(0.01)
    print("Progress {:2.1%}".format(i / 100))

आउटपुट कुछ इस तरह दिखाई देगा:

Progress 0.0%%
Progress 1.0%%
Progress 2.0%%
Progress 3.0%%

स्थायी प्रिंट छोड़ने से पहले लाइन को साफ करने के लिए मेरे लिए क्या काम करता है। अपनी विशिष्ट समस्या के लिए स्वतंत्र महसूस करें:

import time

ERASE_LINE = '\x1b[2K' # erase line command
n = 100
for i in range(100):
    for j in range(100):
        print("Progress {:2.1%}".format(j / 100), end="\r")
        time.sleep(0.01)
    print(ERASE_LINE + "Progress {:2.1%}".format(i / 100)) # clear the line first

और अब यह उम्मीद के मुताबिक प्रिंट करता है:

Progress 0.0%
Progress 1.0%
Progress 2.0%
Progress 3.0%

5

यहाँ एक क्लीनर, अधिक "प्लग-एंड-प्ले", @ नागासाकी 45 के उत्तर का संस्करण है। यहां कई अन्य उत्तरों के विपरीत, यह विभिन्न लंबाई के तारों के साथ ठीक से काम करता है। यह अंतिम पंक्ति में मुद्रित प्रिंट की लंबाई के रूप में केवल कई रिक्त स्थान के साथ लाइन को साफ़ करके इसे प्राप्त करता है। विंडोज पर भी काम करेगा।

def print_statusline(msg: str):
    last_msg_length = len(print_statusline.last_msg) if hasattr(print_statusline, 'last_msg') else 0
    print(' ' * last_msg_length, end='\r')
    print(msg, end='\r')
    sys.stdout.flush()  # Some say they needed this, I didn't.
    print_statusline.last_msg = msg

प्रयोग

बस इसे इस तरह से उपयोग करें:

for msg in ["Initializing...", "Initialization successful!"]:
    print_statusline(msg)
    time.sleep(1)

यह छोटा परीक्षण दिखाता है कि अलग-अलग लंबाई के लिए भी लाइनें ठीक से साफ हो जाती हैं:

for i in range(9, 0, -1):
    print_statusline("{}".format(i) * i)
    time.sleep(0.5)

5
यह एक शानदार समाधान है क्योंकि यह पिछले आउटपुट को अपनी पूरी लंबाई में बिना किसी सफेद जगह के एक मनमानी संख्या को प्रिंट किए बिना साफ करता है (जो कि मैंने पहले इसका सहारा लिया था!) ​​धन्यवाद
— टोबी पेटी

2

मैं थोड़ा हैरान हूं कि कोई भी बैकस्पेस चरित्र का उपयोग नहीं कर रहा है। यहाँ एक है जो इसका उपयोग करता है।

import sys
import time

secs = 1000

while True:
    time.sleep(1)  #wait for a full second to pass before assigning a second
    secs += 1  #acknowledge a second has passed

    sys.stdout.write(str(secs))

    for i in range(len(str(secs))):
        sys.stdout.write('\b')

सुनिश्चित करें कि आप इस विधि का उपयोग करने के बाद फ्लश करते हैं या आपको स्क्रीन पर मुद्रित कुछ भी नहीं मिल सकता है। sys.stdout.flush()
— गेब्रियल फेयर

2

(पायथन 3) मेरे लिए यही काम करता है। यदि आप सिर्फ \ 010 का उपयोग करते हैं तो यह वर्णों को छोड़ देगा, इसलिए मैंने यह सुनिश्चित करने के लिए इसे थोड़ा बदल दिया कि यह क्या है। यह आपको पहले प्रिंट आइटम से पहले कुछ करने की अनुमति देता है और केवल आइटम की लंबाई को हटा देता है।

print("Here are some strings: ", end="")
items = ["abcd", "abcdef", "defqrs", "lmnop", "xyz"]
for item in items:
    print(item, end="")
    for i in range(len(item)): # only moving back the length of the item
        print("\010 \010", end="") # the trick!
        time.sleep(0.2) # so you can see what it's doing

2

प्रचलित उत्तरों के आधार पर एक और उत्तर।

Pbar.py की सामग्री: आयात sys, शील, डेटाइम

last_line_is_progress_bar=False


def print2(print_string):
    global last_line_is_progress_bar
    if last_line_is_progress_bar:
        _delete_last_line()
        last_line_is_progress_bar=False
    print(print_string)


def _delete_last_line():
    sys.stdout.write('\b\b\r')
    sys.stdout.write(' '*shutil.get_terminal_size((80, 20)).columns)
    sys.stdout.write('\b\r')
    sys.stdout.flush()


def update_progress_bar(current, total):
    global last_line_is_progress_bar
    last_line_is_progress_bar=True

    completed_percentage = round(current / (total / 100))
    current_time=datetime.datetime.now().strftime('%m/%d/%Y-%H:%M:%S')
    overhead_length = len(current_time+str(current))+13
    console_width = shutil.get_terminal_size((80, 20)).columns - overhead_length
    completed_width = round(console_width * completed_percentage / 100)
    not_completed_width = console_width - completed_width
    sys.stdout.write('\b\b\r')

    sys.stdout.write('{}> [{}{}] {} - {}% '.format(current_time, '#'*completed_width, '-'*not_completed_width, current,
                                        completed_percentage),)
    sys.stdout.flush()

स्क्रिप्ट का उपयोग:

import time
from pbar import update_progress_bar, print2


update_progress_bar(45,200)
time.sleep(1)

update_progress_bar(70,200)
time.sleep(1)

update_progress_bar(100,200)
time.sleep(1)


update_progress_bar(130,200)
time.sleep(1)

print2('some text that will re-place current progress bar')
time.sleep(1)

update_progress_bar(111,200)
time.sleep(1)

print('\n') # without \n next line will be attached to the end of the progress bar
print('built in print function that will push progress bar one line up')
time.sleep(1)

update_progress_bar(111,200)
time.sleep(1)

1

यहाँ मेरा समाधान है! विंडोज 10, पायथन 3.7.1

मुझे यकीन नहीं है कि यह कोड क्यों काम करता है, लेकिन यह मूल रेखा को पूरी तरह से मिटा देता है। मैंने पिछले उत्तरों से इसे संकलित किया। अन्य उत्तर बस शुरुआत में लाइन को वापस कर देंगे, लेकिन यदि आपके पास बाद में एक छोटी रेखा होती है, तो यह helloबदल जाता है जैसे कि गड़बड़ हो जाएगा byelo।

import sys
#include ctypes if you're on Windows
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
#end ctypes

def clearline(msg):
    CURSOR_UP_ONE = '\033[K'
    ERASE_LINE = '\x1b[2K'
    sys.stdout.write(CURSOR_UP_ONE)
    sys.stdout.write(ERASE_LINE+'\r')
    print(msg, end='\r')

#example
ig_usernames = ['beyonce','selenagomez']
for name in ig_usernames:
    clearline("SCRAPING COMPLETE: "+ name)

आउटपुट - किसी भी पुराने पाठ को दिखाए बिना प्रत्येक पंक्ति को फिर से लिखा जाएगा:

SCRAPING COMPLETE: selenagomez

अगली पंक्ति (एक ही पंक्ति पर पूरी तरह से लिखी गई):

SCRAPING COMPLETE: beyonce

0

पूरी लाइन को ओवरराइट करने के लिए बेहतर है अन्यथा नई लाइन पुरानी होने पर नई लाइन के साथ मिक्स हो जाएगी।

import time, os
for s in ['overwrite!', 'the!', 'whole!', 'line!']:
    print(s.ljust(os.get_terminal_size().columns - 1), end="\r")
    time.sleep(1)

columns - 1विंडोज पर उपयोग करना था ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.