python - 从屏幕上删除打印的行

标签 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') (取消注释上面的行)但是这段代码似乎在主线程中的后续打印之后运行,并且它没有删除任何内容。为什么是这样?一个更明显的例子,我在返回 else 之前使用 sys.stdout.write('TEST')

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()                                                                                                                                                                                                                                                    

最佳答案

问题是主线程不等待 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 (*)

(*) 即使在 finaly block 之后 旋转之后发生了 write,我也可以证明主线程开始在 stdout 上写入线程可以通过在线程末尾写入可打印字符来写入最后一个退格键。该字符打印得太晚了。

如何修复:只需加入 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

关于python - 从屏幕上删除打印的行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39975187/

相关文章:

java - Spring @ExceptionHandler 和多线程

python - 内存蛋花

android - 无法使用适用于 Android 4 的代码在未调用 Looper.prepare() 的线程内创建处理程序

Android:定期执行代码

java - 定时器类中潜在的竞争条件?

c++ - 从 std::deque 线程安全地同时调用 emplace_back() 和 operator[]() 吗?

python - 冗余关键字参数

php - 混合使用 Python 和 PHP?

python - 如何在不使用任何库的情况下使用 Python 实现一个简单的 Web 服务器?

python - 如何在python中定义具有不同值的全局变量