redirect sys.stdout to specific Jupyter Notebook cell
The documentation for ipywidgets.Output
has a section about interacting with output widgets from background threads. Using the Output.append_stdout
method there is no need for locking. The final cell in this answer can then be replaced with:
def t1_main(): for i in range(10): output1.append_stdout(f'thread1 {i}\n') time.sleep(0.5)def t2_main(): for i in range(10): output2.append_stdout(f'thread2 {i}\n') time.sleep(0.5)output1.clear_output()output2.clear_output() t1 = Thread(target=t1_main)t2 = Thread(target=t2_main)t1.start()t2.start()t1.join()t2.join()
You can use a combination of ipywidgets.Output
(docs) and locking:
Code in jupyter cells:
# In[1]:from threading import Thread, Lockimport timefrom ipywidgets import Output# In[2]:output1 = Output()output1# In[3]:output2 = Output()output2# In[4]:print_lock = Lock()def t1_main(): for i in range(10): with print_lock, output1: print('thread1', i) time.sleep(0.5)def t2_main(): for i in range(10): with print_lock, output2: print('thread2', i) time.sleep(0.5)output1.clear_output()output2.clear_output() t1 = Thread(target=t1_main)t2 = Thread(target=t2_main)t1.start()t2.start()t1.join()t2.join()