एक ही लाइन पिछले आउटपुट को ओवरराइट करने के लिए आउटपुट?


97

मैं एक एफ़टीपी डाउनलोडर लिख रहा हूँ। कोड का हिस्सा कुछ इस तरह है:

ftp.retrbinary("RETR " + file_name, process)

मैं कॉलबैक को संभालने के लिए फ़ंक्शन प्रक्रिया को कॉल कर रहा हूं:

def process(data):
    print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
    file.write(data)

और आउटपुट कुछ इस तरह है:

1784  KB / KB 1829 downloaded!
1788  KB / KB 1829 downloaded!
etc...   

लेकिन मैं चाहता हूं कि वह इस लाइन को प्रिंट करे और अगली बार इसे रीफ़्रेश / रीफ़्रेश करें ताकि यह केवल एक बार दिखाई दे और मुझे उस डाउनलोड की प्रगति दिखाई दे।

यह कैसे किया जा सकता है?



जवाबों:


189

यहाँ अजगर 3.x के लिए कोड है:

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!', end='\r')

end=कीवर्ड यहां काम करता है क्या है - डिफ़ॉल्ट रूप से, print()एक नई पंक्ति (में समाप्त होता है \n) चरित्र, लेकिन यह एक अलग तार के साथ बदला जा सकता है। इस स्थिति में, गाड़ी के बदले लाइन को समाप्त करने के बजाय कर्सर को चालू लाइन की शुरुआत में लौटाता है। इस प्रकार, sysइस तरह के सरल उपयोग के लिए मॉड्यूल को आयात करने की कोई आवश्यकता नहीं है । print()वास्तव में कई कीवर्ड तर्क हैं जिनका उपयोग कोड को सरल बनाने के लिए किया जा सकता है।

पायथन 2.6+ पर समान कोड का उपयोग करने के लिए, फ़ाइल के शीर्ष पर निम्न पंक्ति रखें:

from __future__ import print_function

6
ध्यान दें कि फ़ाइल के शीर्ष पर निम्न आयात जोड़कर प्रिंट फ़ंक्शन का उपयोग अजगर 2.6+ में भी किया जा सकता है from __future__ import print_function:।
जानिन

12
अजगर में 3.0 बयान के अंत में एक अल्पविराम "\ n" को रोक देगा: print "foo",हालाँकि आपको अभी भी परिवर्तन देखने के लिए इसके बाद फ्लश करने की आवश्यकता है:sys.stdout.flush()
टोबियास डोमन

31
मैंने पाया कि मुझे \rस्ट्रिंग की शुरुआत में शामिल करने की आवश्यकता है , और end=''इसे काम करने के लिए सेट करें। मुझे नहीं लगता कि जब मैं खत्म होता हूं तो मेरा टर्मिनल इसे पसंद करता है\r
Jezzamon

2
सभी मौजूदा पायथन 3 रिलीज में, आप बफर को निस्तब्धता सुनिश्चित flush=Trueकरने के लिए print()फ़ंक्शन में जोड़ सकते हैं (एक \nनई पंक्ति लिखे जाने पर मानक लाइन बफर केवल फ्लश होगा )।
मार्टिन पीटर्स

4
एक बृहस्पति नोटबुक में, \rशुरुआत में और end=''सबसे अच्छा और सुचारू रूप से काम कर रहा था। का उपयोग flush=Trueके साथ \rअंत में अगर स्ट्रिंग और end='\r'भी काम किया लेकिन चिकनी नहीं किया गया था और लाइन और उसके linefeed मिट।
डेव एक्स

40

यदि आप सभी करना चाहते हैं तो एक लाइन को बदल दें, उपयोग करें \r\rमतलब गाड़ी वापसी। वर्तमान लाइन की शुरुआत में कार्यवाहक वापस रखना पूरी तरह से प्रभावी है। यह कुछ भी नहीं मिटाता है। इसी तरह, \bएक चरित्र को पिछड़े जाने के लिए इस्तेमाल किया जा सकता है। (कुछ टर्मिनल उन सभी सुविधाओं का समर्थन नहीं कर सकते हैं)

import sys

def process(data):
    size_str = os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!'
    sys.stdout.write('%s\r' % size_str)
    sys.stdout.flush()
    file.write(data)

1
मैं \rजोड़ूंगा कि गाड़ी वापसी का मतलब है। इसका असर पूरी तरह से करंट को मौजूदा लाइन के शुरू में वापस लाने के लिए है। यह कुछ भी नहीं मिटाता है। इसी तरह, \bएक चरित्र पिछड़े जाने के लिए इस्तेमाल किया जा सकता है। (कुछ टर्मिनल उन सभी विशेषताओं का समर्थन नहीं कर सकते हैं)
एड्रियन प्लिसन

sys.stdout.write('%s\r', size_str')मुझे लगता है कि तुम मतलब है, sys.stdout.write('%s\r' % size_str)लेकिन यह काम नहीं करता है।
क्रिस्टियन

@ एड्रियन: कूल, कहा कि। @ क्रिश्चियन: धन्यवाद, अपडेट किया गया, यह बहुत देर हो चुकी थी।
सैम डोलन

यह भी ध्यान दें कि आप अभी भी उपयोग कर सकते printहैं sys.stdout.writeयदि आप पसंद करते हैं: print size_str + "\r",ठीक काम करता है। ,प्रिंट बयान के अंत में नई पंक्ति को दबा; sys.stdout.flush()अभी भी जरूरत है
जेफ

19

शाप मॉड्यूल प्रलेखन और शाप मॉड्यूल HOWTO पर एक नजर है ।

वास्तव में मूल उदाहरण:

import time
import curses

stdscr = curses.initscr()

stdscr.addstr(0, 0, "Hello")
stdscr.refresh()

time.sleep(1)

stdscr.addstr(0, 0, "World! (with curses)")
stdscr.refresh()

10
दुर्भाग्य से, शाप केवल यूनिक्स पर उपलब्ध है। ओपी ने हमें यह नहीं बताया कि उसका एप्लिकेशन किस ऑपरेटिंग सिस्टम को लक्षित कर रहा है ...
एड्रियन प्लिसन

मुझे लिनक्स के तहत काम करने की आदत है कि मैंने मॉड्यूल डॉक्स में केवल UNIX के लिए मॉड्यूल के बारे में चेतावनी को नोटिस नहीं किया था .. जो कि बाहर इंगित करने के लिए धन्यवाद, @ Adrien।
एंड्रिया स्पैडैसिनी

3
@ AdrienPlisson, मुझे पता है कि यह सवाल सालों पहले बनाया गया था, लेकिन आप वास्तव में Windows पर Curses
कोल्ड

जब मैंने इसे अपने पायथन इंटरप्रेटर में चिपकाया, तो मेरा टर्मिनल फ्यूबर हो गया। दुभाषिया से बाहर निकलने से कोई फायदा नहीं हुआ। WTF ?!
अल्लौरकोड

उपयोग clrtoeolके लिए जब दूसरी पंक्ति पहले की तुलना में कम है।
सर्ज स्ट्रोबंड्ट

9

यहां मेरी छोटी कक्षा है जो पाठ के ब्लॉक को पुन: प्रिंट कर सकती है। यह पिछले पाठ को ठीक से साफ कर देता है ताकि आप अपने पुराने पाठ को गड़बड़ किए बिना छोटे नए पाठ के साथ अधिलेखित कर सकें।

import re, sys

class Reprinter:
    def __init__(self):
        self.text = ''

    def moveup(self, lines):
        for _ in range(lines):
            sys.stdout.write("\x1b[A")

    def reprint(self, text):
        # Clear previous text by overwritig non-spaces with spaces
        self.moveup(self.text.count("\n"))
        sys.stdout.write(re.sub(r"[^\s]", " ", self.text))

        # Print new text
        lines = min(self.text.count("\n"), text.count("\n"))
        self.moveup(lines)
        sys.stdout.write(text)
        self.text = text

reprinter = Reprinter()

reprinter.reprint("Foobar\nBazbar")
reprinter.reprint("Foo\nbar")

2
यह विंडोज में नहीं होगा काम विंडोज 10 तक, क्योंकि Windows 10 पहले खिड़कियों उन नियंत्रण वर्ण का समर्थन करने के en.wikipedia.org/wiki/ANSI_escape_code
user136036

8

मैंने पाया कि अजगर 2.7 में एक साधारण प्रिंट स्टेटमेंट के लिए, अपने अंत में एक अल्पविराम लगाएं '\r'

print os.path.getsize(file_name)/1024, 'KB / ', size, 'KB downloaded!\r',

यह अन्य गैर-पायथन 3 समाधानों की तुलना में कम है, लेकिन इसे बनाए रखना और भी मुश्किल है।


1
अजगर 2.7.10, और यह कुछ भी नहीं छाप रहा है। हो सकता है, आप इसे ऑनलाइन संकलित कर सकें और हमें यह देखने के लिए लिंक भेज सकें कि यह कैसे काम कर रहा है ...?
श्योगो माशिमिमा

5

आप प्रिंट फ़ंक्शन के अंत में स्ट्रिंग प्लस के अंत में '\ r' जोड़ सकते हैं। उदाहरण के लिए:

print(os.path.getsize(file_name)/1024+'KB / '+size+' KB downloaded!\r'),

1
यह अजगर 3 के लिए है? यदि ऐसा है तो डिफ़ॉल्ट endपैरामीटर क्या \nयू प्रिंट में सेट है (...)KB downloaded!\r\n। क्या मै गलत हु?
एसआर

का उपयोग करते हुए end = '\r'बजाय पायथन 3. में समस्या का समाधान होता
अभिमन्यु पल्लवी सुधीर

4

मैं स्पाइडर 3.3.1 - विंडोज 7 - अजगर 3.6 का उपयोग कर रहा हूं, हालांकि फ्लश की आवश्यकता नहीं हो सकती है। इस पोस्टिंग के आधार पर - https://github.com/spyder-ide/spyder/issues/3437

   #works in spyder ipython console - \r at start of string , end=""
import time
import sys
    for i in range(20):
        time.sleep(0.5)
        print(f"\rnumber{i}",end="")
        sys.stdout.flush()

1

अजगर में पिछली पंक्ति को ओवरवाइट करने के लिए आपको जो भी ज़रूरत है वह प्रिंट फंक्शन में अंत = 'आर' जोड़ना है , इस उदाहरण का परीक्षण करें:

import time
for j in range(1,5):
   print('waiting : '+j, end='\r')
   time.sleep(1)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.