class MyClass():
def __init__(self):
...
def start(self):
colorThread = threading.Thread(target = self.colorIndicator())
colorThread.start()
while True:
print ('something')
...
...
I also have a print statement inside the colorIndicator(). That statement is getting printed. But the print statement inside the while loop of start() method isn't displayed on screen.
The colorIndicator() also has an infinite loop. It gets some data from the internet and updates a counter. This counter is initialized inside __init__ as self variable and I'm using that variable inside other methods.
I do not understand why print inside while is not being executed.
colorIndicator function:
def colorIndicator(self):
print ('something else')
...
while (True):
...
print ('here')
time.sleep(25)
The output I get is the following:
something else
here
here
I stopped it after that. So, the colorIndicator is clearly running completely.
I'm calling the script with import in a python interpreter (in a terminal). Then I instantiate MyClass and call the start function.
You're not actually running colorIndicator in a thread, because you called it in the main thread, rather than passing the method itself (uncalled) as the thread target. Change:
colorThread = threading.Thread(target=self.colorIndicator())
# ^^ Agh! Call parens!
to:
# Remove parens so you pass the method, without calling it
colorThread = threading.Thread(target=self.colorIndicator)
# ^ Note: No call parens
Basically, your problem is that before you ever construct the Thread, it's trying to run colorIndicator to completion so it can use its return value as the target, which is wrong in multiple ways (the method never returns, and even if it did, it wouldn't return a callable suitable for use as a target).
Related
I have a function and it prints things but this function gets an error for some values. So I used a try/except block to solve this but even if the fuction gets an error it keeps printing until the error. The function looks like this:
def error_solver(x):
try:
function(x)
except:
error_solver(x+1)
error_solver(0)
If you can't understand what I'm talking about here is another example:
def f(x):
try:
function_1()
function_2()
except:
pass
Let's say an error occurs in function_2(). In this case if function_1() works without errors it will be executed. I don't want this to happen and just end the fuction without executing the first function. How can i solve this problem?
You can prevent leaving a halfway through try - except block by either restoring the system to either a previous, or a well known state, or by buffering the result of the try block, and only applying the result at the end of the try block.
If the only thing done by your functions is printing, then the last method might make sense:
Instead of printing to the screen, you could print to a string, and only at the end print the resulting string to the screen. For this to work, you will have to modify function_1() and function_2() to take a file argument:
import io, sys
def function_1(file):
print("hi from function_1", file=file)
def function_2(file):
print("hi from function_2", file=file)
def f(x):
try:
with io.StringIO() as file:
function_1(file)
function_2(file)
sys.stdout.write(file.getvalue())
except:
pass
In your example function_1 will always execute before function_2, regardless if function_2 fails or not. If you need your function_1(); function_2() operation to be transactional (both succeed or nothing happens), you can add an explicit undo operation:
def f(x):
try:
function_1()
function_2()
except Function2Error:
undo_function_1()
Python will execute all the lines till it reaches the error line. So we can't undo the operations that executed in function_1.
Following a tutorial on Python's debugger, I used pdb.set_trace() to interrupt the sample code. It worked, but what if you are at the interactive prompt and want another nested breakpoint?
(Pdb) def test(): pdb.set_trace(); print "don't print this yet"
(Pdb) test()
don't print this yet
It didn't stop. Is the debugger fundamentally "one deep"? e.g. is this is a limitation of Python's hooks, or just something pdb doesn't choose to do?
is this is a limitation of Python's hooks, or just something pdb doesn't choose to do?
It appears to be a limitation of the hooks.
I did a test to see what was being called and what wasn't (putting print statements in /usr/lib/python2.7/bdb.py)
Quick inspection finds set_trace in pdb.py:
def set_trace():
Pdb().set_trace(sys._getframe().f_back)
That calls set_trace in bdb.py
def set_trace(self, frame=None):
"""Start debugging from `frame`.
If frame is not specified, debugging starts from caller's frame.
"""
if frame is None:
frame = sys._getframe().f_back
self.reset()
while frame:
frame.f_trace = self.trace_dispatch
self.botframe = frame
frame = frame.f_back
self.set_step()
sys.settrace(self.trace_dispatch)
This sets up a callback to trace_dispatch, also in bdb.py. The sys.settrace code itself is perhaps in threading.py:
def settrace(func):
global _trace_hook
_trace_hook = func
GitHub search finds no more references for _trace_hook, so presumably that's picked up magically in C code somewhere.
When test() is called, it turns out the sys.settrace() call is made...but then the call to trace_dispatch() does not happen.
I am trying to quit a python program by calling sys.exit() but it does not seem to be working.
The program structure is something like:
def func2():
*does some scraping operations using scrapy*
def func1():
Request(urls, callbakc=func2)
So, here, func1 is requesting a list of URLs and the callback method, func2 is being called. I want to quit the execution of the program if something goes wrong in func2
On checking the type of the object in func1 I found its and http.Request object.
Also, since I am using scrapy, whenever I call sys.exit() in func2, the next url in the list is called and the program execution continues.
I have also tried to use a global variable to stop the execution but to no avail.
Where am I going wrong?
According to the How can I instruct a spider to stop itself?, you need to raise CloseSpider exception:
raise CloseSpider('Done web-scraping for now')
Also see:
Running Scrapy tasks in Python
sys.exit() would not work here since Scrapy is based on twisted.
Even if we don't know how to completely stop, Python's mutable-object default binding "gotcha" can help us skip all callbacks from a certain point on.
Here is what you can do:
First, create a function generating wrapping other callback functions with condition. It's second argument cont is going to be bound to a mutable object (list) so we can affect all callbacks after creating them.
def callback_gen(f, cont=[True]):
def c(response):
if cont[0]:
f(response, cont=cont)
else:
print "skipping" # possibly replace with pass
return c
Now make some testing functions:
def func2(response, cont=None):
print response
print cont
# this should prevent any following callback from running
cont[0]=False
def func3(response, cont=None):
print response
print cont
And now create two callbacks the first one is func2 which prevents the following ones from running.
f2 = callback_gen(func2)
f3 = callback_gen(func3)
f2("func2")
f3("func3")
I like it :)
I have a problem in managing a infinite while loop in Python, in which I would insert a timer as a sort of "watchdog". I try to explain better: the script has to listen on a serial channel and wait for messages coming from sensors connected on the other side of the channel.
I do this with a while True loop because the script must catch all the signals that are passing. However, even if it's probably unnecessary, i would like to insert a timer which is always reset every loop. So, if (for example) the loop get stuck for some reason, the timer will end and will exit the program. I thought i could do this in this way:
def periodicUpdate():
exitTimer = threading.Timer(60.0, sys.exit())
while True:
exitTimer.start()
readData()
exitTimer.cancel()
Now, the problem is that when i start the script it immediatly exit. It seems that it reads sys.exit() before all the rest, and it doesn't respect the construct of the timer, but simply when periodicUpdate is called it exits. Why this happen?! I tried changing the syntax, putting sys.exit in an other function and call that function, i tried other solutions but always it behave in two ways: it exits or it behave as the timer doesn't exists. Can someone help me? Thanks very much
Remove the parentheses. If you use sys.exit(), it will fire straight away. When you use sys.exit, it will pass the function as Timer's second argument.
I think your approach is not the best one, instead of running a timer that exits the application, why not simply timeout the function that reads the data:
Timeout on a function call
It seems that it reads sys.exit() before all the rest
Sure it does. The second argument of threadint.Timer is a function that will be called. What you do is you actually call sys.exit and supply its return value (which is undefined, by the way, since the call terminates the program) as a function to be called. That's an error, since sys.exit's return value is not a function, but that doesn't matter, as the program is terminated anyway.
What you want to do is
exitTimer = threading.Timer(60.0, sys.exit) # note: no brackets
But that actually will not work, as sys.exit in the thread will terminate only that thread. In short, you can't use a watchdog to terminate a stuck while-loop if this loops is in your main thread. In your particular situation you should investigate the function you are using to read data, most likely it lets you set a read timeout.
It seems to me that none of the solutions proposed here actually works. This is an example of code. Would be great to know how to fix it. Also, please try it before answering.
import time, threading, sys
def _exit():
print 'exiting'
sys.exit()
def periodicUpdate():
exitTimer = threading.Timer(2.0, _exit)
while True:
exitTimer.start()
print 'go'
time.sleep(5)
exitTimer.cancel()
periodicUpdate()
The actual output is:
$python test.py
go
exiting
RuntimeError: threads can only be started once
exitTimer = threading.Timer(60.0, sys.exit)
Remove the () from sys.exit in timer call
def _exit()
sys.exit()
def periodicUpdate():
exitTimer = threading.Timer(60.0, _exit)
while True:
exitTimer.start()
readData()
exitTimer.cancel()
In you put the () the interpreter call this function if not the interpreter get a reference for this function.
Have fun :)
Edit: Use of _exit
threading.Timer(60.0, os._exit, [0])
def periodicUpdate():
exitTimer = sys.exit(60.0, sys.exit())
while sys.exit():
sys.exit()
readData()
sys.exit()
if __name__ == "__main__":
sys.exit()
Don't forget to import sys.
i want to execute a function in every 3 second
the code works if i call a function without arguments like below:
def mytempfunc():
print "this is timer!"
threading.Timer(5, mytempfunc).start()
but if i call a function with argument like this:
def myotherfunc(a,b,c,d):
print "this is timer!"
threading.Timer(5, myotherfunc(a,b,c,d)).start()
the new thread will be created and started immediately without waiting for 5 seconds.
is there anything that i missed?
Try this:
threading.Timer(5, myotherfunc, [a,b,c,d]).start()
In your code, you actually call myotherfunc(a,b,c,d), rather than passing your function and arguments to the Timer class.