I have a running
variable which is responsible for whether the program is running or not. There is also a loop that runs as long as running == True
. This loop contains many functions, each of which takes, say, 1 second to complete.
Thus, if during the iteration of the loop the value of running
is changed to False
until the iteration is completely completed, the actions will be performed.
It is necessary for me that as soon as the value of running
becomes False
, the cycle is interrupted immediately (well, or almost immediately).
I have this solution:
running = True
while running:
do_something1(time_length=1)
if not running:
break
do_something2(time_length=1)
if not running:
break
do_something3(time_length=1)
if not running:
break
do_something4(time_length=1)
if not running:
break
do_something5(time_length=1)
if not running:
break
do_something6(time_length=1)
if not running:
break
# etc.
However, this option looks very clumsy and takes up a lot of space. Is it possible not to prescribe a condition before each action, but to prescribe it, say, only at the beginning?
UPD 1: Due to the fact that I did not fully show the code, the answers do not quite suit me, as I understand it.
All variables and functions are inside the class. The code itself looks like this.
from threading import Thread
class SomeClass:
def __init__(self):
self.running = True
def toggle_running_flag(self):
# this function toggles self.running by user input
self.running = not self.running
if self.running:
Thread(target=self.do_all_of_this).start()
def do_something1(self):
# do something
pass
def do_something2(self):
# do something
pass
def do_something3(self):
# do something
pass
def do_all_of_this(self):
while self.running:
self.do_something1()
if not self.running:
break
self.do_something2()
if not self.running:
break
self.do_something3()
CodePudding user response:
Instead of that flag variable, you could use an exception. Note that exceptions aren't just for "bad stuff", for example the StopIteration
exception is how iterators signal that they're done.
Demo:
from contextlib import suppress
class StopRunning(Exception):
pass
def do_something1():
print('do_something1')
raise StopRunning
def do_something2():
print('do_something2')
with suppress(StopRunning):
while True:
do_something1()
do_something2()
print('done')
Output:
do_something1
done
CodePudding user response:
The is a way you can do that. You can create a function that will loop indefinitely between the functions you have to execute:
from itertools import cycle
class SomeClass:
def __init__(self):
self.running = True
def toggle_running_flag(self):
# this function toggles self.running by user input
self.running = True
Thread(target=self.do_all_of_this).start()
def do_all_of_this(self):
self.work = [self.do_something1, self.do_something2, self.do_something3]
for func in cycle(self.work):
func()
if not self.running:
return
After every iteration check if your program should still be running. If not return (Stop iteration)
CodePudding user response:
Are the various do_something
s setting running = False
? Relying on globals isn't a great pattern.
One alternative to updating a global flag is to have do_somethingN
throw an exception to stop execution:
from do_things import StopRunning, do_something1, do_something2, # etc
try:
while True:
do_something1(time_length=1)
do_something2(time_length=1)
do_something3(time_length=1)
do_something4(time_length=1)
do_something5(time_length=1)
do_something6(time_length=1)
except StopRunning:
pass
Elsewhere:
# do_things.py
class StopRunning(Exception):
pass
def do_something1(time_length):
if time_length > 42:
raise StopRunning
# etc