Currently trying to do an idle animation which constantly updates the character when idle = True, trying to also keep it mainly in a function for later use as well.
However, when I updated idle = False outside of the function, it didn't stop the animation.
I came across threading, which seemed to solve some issues for a bit.
import time
import threading
b = True
def test_func():
global b
while b:
print '1'
threading.Thread(target=test_func).start()
b = False
This worked, but it would be easier for the function to accept things like
def test_func(b):
and have that be used instead of a lot of global variables. Especially when I use it for multiple things, it would be helpful to have it just accept which one will be checked instead of way more lines. When trying to do
import time
import threading
b = True
def test_func(b):
while b:
print '1'
threading.Thread(target=test_func(b)).start()
b = False
the (b) seems to make the threading not work as it constantly goes instead of stopping when b = False
(this is my small test code where b represents the boolean for if it continues to update and the print '1' part is in place of the character updating.) (also I tried using lambda because that's what I remember worked in other cases when I needed to pass a variable like that but I tested it and it doesn't work)
When you write threading.Thread(target=test_func(b)).start()
the function is called as part of collecting the arguments to Thread
, before the thread is started; in addition, the function gets a copy of the variable, rather than the variable itself.
In order to make something like this work, you need to resolve both halves:
Make it accept an argument, but then still be a function that will be called
This can be done in a few ways. Probably the cleanest would be to make test_func
part of an object, so that you pass b
to the constructor and then have a method as the thread:
threading.Thread(target=Worker(b).test_func).start()
That's usually the best, because it gives you a place for all your thread-related data and functions (they all live in the same object).
If that's too much, if you really do have just one function that you need to call like this, you can use functools.partial
or a closure:
threading.Thread(target=partial(test_func, b)).start()
Use a mutable value which you can modify in-place
When you pass a boolean into a function, that function effectively gets a copy. You'll need to use some mutable value (object, list, etc) which you can change in-place.
If you use an object for the first item, that's probably easiest:
w = Worker()
threading.Thread(target=w.test_func).start()
w.b = False
Otherwise, you can make b
a dict or list or similar, then change a particular entry within it:
threading.Thread(target=partial(test_func, b)).start()
b['active'] = False