everyone!
I want to be able to print in Python multiple "blocks" of print statements. I will directly give an example to be easier.
Let's say I want to print the first 100 numbers and, while this is done, to have a separate print statement that keeps updating (this statement should be printed before). Basically, the output should be like this:
Output Statement 1 # <- This should keep updating to "Output Statement 2" than back to "Output Statement 1"
# and so on
Number 1 Number 2 Number 3 ....
If I want to print only "Output Statement 1" and keep updating this, it works, as long as it is the only "block" of print statements. But while "Output statement x" should be printed and updating, the second "block" of prints, where numbers from 1 to 100 should be shown, must also run.
What did I try:
I have created two functions, one for the first block and one for the second. Then, in main, I have created 2 separate threads, to which I assigned each of those 2 functions. The first thread, which should be responsible for the updated message, was set as daemon, because I want to continuously run until the program ends. I also set a sleep of a couple of seconds between the moment in which I start the first and the second thread.
Below is my code:
import time
import threading
def change_msg():
while True:
print("Out Message 1", end='\r', flush=True)
time.sleep(1)
print("Out Message 2", end='\r', flush=True)
time.sleep(1)
def print_numbers():
print("\n")
print("Starting numbers...")
for i in range(5):
print("Number", i 1)
time.sleep(5)
print("Finishing numbers...")
if __name__ == "__main__":
thread_1 = threading.Thread(target=change_msg, daemon=True)
thread_2 = threading.Thread(target=print_numbers)
thread_1.start()
time.sleep(5)
thread_2.start()
But the output I get is this one:
Out Message 1
Starting numbers...
Number 1
Number 2age 2
Number 3age 1
Number 4age 2
Number 5age 1
Finishing numbers...
I see that, even they are separate threads, the prints are overlapping.
How can I "separate" those 2 output sets, so they are independent? In case it's possible, of course.
P.S. I use Python 3.9
Thanks!
CodePudding user response:
Since you're trying to print to things at the same time, you'd need 2 outputs.
Possible solutions I see:
- Split the Terminal into right-left. But not shure how you'd do that tho.
- Create a shared "blocking" variable, which indicates if a process is currently printing.
CodePudding user response:
The issue you are experiencing is due to the fact that both threads are trying to write to the same console output at the same time, which can cause the output to become mixed or jumbled. One way to solve this problem is to use a queue to separate the output from the two threads. You can use the Queue class from the queue module to create a queue that the first thread can use to send messages to be printed, and the second thread can use to retrieve and print the messages. Here's an example code :
import time
import threading
from queue import Queue
def change_msg(queue):
while True:
queue.put("Out Message 1")
time.sleep(1)
queue.put("Out Message 2")
time.sleep(1)
def print_numbers(queue):
print("\n")
print("Starting numbers...")
for i in range(5):
print("Number", i 1)
time.sleep(5)
print(queue.get())
print("Finishing numbers...")
if __name__ == "__main__":
queue = Queue()
thread_1 = threading.Thread(target=change_msg, args=(queue,), daemon=True)
thread_2 = threading.Thread(target=print_numbers, args=(queue,))
thread_1.start()
time.sleep(5)
thread_2.start()
output :
Starting numbers...
Number 1
Out Message 1
Number 2
Out Message 2
Number 3
Out Message 1
Number 4
Out Message 2
Number 5
Out Message 1
Finishing numbers...