从屏幕上删除打印的行

时间:2016-10-11 10:21:49

标签: python multithreading

我有运行不同时间长度的代码,在此期间线程运行并显示旋转光标。当代码完成它的任务时,它打印一些输出,设置一个事件,光标停止。但是,这会留下屏幕上打印的最后一个字符。我希望将其删除。

def spinning_cursor(event):                                                    
    for j in itertools.cycle('/-\|'):                                           
        if not event.is_set():                                                 
            sys.stdout.write(j)                                                
            sys.stdout.flush()                                      
            time.sleep(0.1)                                                    
            sys.stdout.write('\b')                                              
        else:  
            #sys.stdout.write('\b')                                                                                                                   
            return  

我在屏幕上看到的内容如下:

paul#
Writing file...
/
info: file has been written
paul# 

我希望/在设置事件时消失。我在返回之前尝试过sys.stdout.write('\b')(取消注释上面的行)但是这个代码似乎在主线程中的后续打印之后运行,并且它什么都没删除。为什么是这样?一个更明显的例子,我在sys.stdout.write('TEST')返回之前使用else

paul#
Writing file...
/
info: file has been written
TESTpaul# 

我通过在主线程中的打印之前向上移动一行来找到解决方案,但由于存在许多代码路径,因此它很混乱:

CURSOR_UP_ONE = '\x1b[1A'                                                                                          
sys.stdout.write(CURSOR_UP_ONE)

以下是旋转光标的调用方式。有什么想法吗?

def copy():                                                                                                                                                                                                                                                   
    processing_flag = Event()                                                                                                                                                                                                                                                        
    Thread(target = spinning_cursor, kwargs = {'event': processing_flag}).start()                                                                                                                                                                                                                                                                                                                                                                                                                                                              
    try:                                                                                                                                                                                                                                                                         
        ...                                                                                                                                                                                                                                                  
    except: 
        ...                                                                                                                                                                                                                                                             
    finally:                                                                                                                                                                                                                                                                     
        processing_flag.set()                                                                                                                                                                                                                                                    

1 个答案:

答案 0 :(得分:1)

问题是主线程不等待 spinning_cursor 。所以这是发生的事情(我可以​​重现它):

main                                     | spinning
---------------------------------------------------------------------------
starts spinning thread                   | starts
works                                    | displays a *spinning* cursor
ends working                             | ==
sets event                               | waits for running time
continues and writes to stdout  (*)      | may be still waiting ...  
...                                      | writes its last backspace and exits (*)

(*)我可以证明主线程开始在stdout上写,即使在write阻止之后发生finaly 旋转线程可以写出它的最后一个退格通过在线程的末尾写一个可打印的字符。这个角色印得太晚了。

如何修复:只需join spinning_cursor 线程:

def copy():
    processing_flag = Event()
    t = Thread(target = spinning_cursor, kwargs = {'event': processing_flag})
    t.start()
    try:
        ...
    except:
        ...
    finally:
        processing_flag.set()
        t.join() # waits for the thread to output its last backspace