Python: global & change var reference - python

Okay, I've been doing some tests, so I need to check the result every time I run a method. Because the test doesn't work properly.
I've made an example that works fine(not a test, but same behavior). In my test the result doesn't change, while in the example it changes.
EXAMPLE
def thread():
global result
import time
time.sleep(0.5)
result = 5/2
Gtk.main_quit()
import threading
from gi.repository import Gtk
result = None
t = threading.Thread(target=thread, args=())
t.start()
Gtk.main()
print result
OUTPUT: 2
TEST
def testSi_Button_clicked(self):
def thread(button=self.builder.get_object('Si_Button')):
import time
global result
time.sleep(0.5)
result = self.esci.Si_Button_clicked(button)
print 'result ' + str(result)
#Gtk.main_quit()
import threading
self.current_window = 'Home_Window' #DO NOT TRY WITH 'Azioni_Window'
result = None
t = threading.Thread(target=thread, args=())
t.start()
Gtk.main()
print 'assert'
print 'result ' + str(result)
self.assertIsNotNone(result)
OUTPUT:
Home_Window
return true
result True
assert
result None
F
======================================================================
FAIL: testSi_Button_clicked (testC_Esci.tstEsci)
----------------------------------------------------------------------
Traceback (most recent call last):
File "testC_Esci.py", line 78, in testSi_Button_clicked
self.assertIsNotNone(result)
AssertionError: unexpectedly None

In thread, global result refers to a module-level variable named result in the module where testSi_Button_clicked (or rather, the class that defines testSi_Button_clicked) is defined. It does not refer to the local variable of the same name that you define in testSi_Button_clicked.
To fix, make result a mutable object (such as a dict), drop the global result statement, and let thread be a closure over result. (In Python 3, you can use the nonlocal keyword to avoid this kind of wrapper trickery.)
def testSi_Button_clicked(self):
def thread(button=self.builder.get_object('Si_Button')):
import time
time.sleep(0.5)
result['result'] = self.esci.Si_Button_clicked(button)
print 'result ' + str(result['result'])
#Gtk.main_quit()
import threading
self.current_window = 'Home_Window' #DO NOT TRY WITH 'Azioni_Window'
result = {'result': None}
t = threading.Thread(target=thread, args=())
t.start()
Gtk.main()
print 'assert'
print 'result ' + str(result['result'])
self.assertIsNotNone(result['result'])

Related

How to run two function in the same time with using try exception block

from Make 2 functions run at the same time by using thread. It can make two function with the same time. Is it possible to call function with thread in try except block?
import threading
from threading import Thread
import time
def queryRepeatedly():
while True:
while True:
try:
Thread(target = foo).start()
Thread(target = bar).start()
print ''
except:
continue
else:
break
def foo():
print 'foo'
time.sleep(1)
def bar():
print 'bar'
time.sleep(3)
queryRepeatedly()
This my code not work,i need to run two function separately with try except block. what should i do?
I think this might be what you're looking for:
import threading
from threading import Thread
import time
def queryRepeatedly():
Thread(target = foo).start()
Thread(target = bar).start()
def foo():
while True:
try:
print 'foo'
except : #catch your error here
pass # handle your error here
finally:
time.sleep(1)
def bar():
While True:
try:
print 'bar'
except : #catch your error here
pass # handle your error here
finally:
time.sleep(3)
queryRepeatedly()

Why can't multiprocess.Process call getattr method?

Trying to call two methods say_hello and say_world by getattr() in multiprocessing.Process, but method say_world hasn't been executed. How can I make it possible? Thanks.
# -*- coding: utf-8 -*-
from multiprocessing import Process
import time
class Hello:
def say_hello(self):
print('Hello')
def say_world(self):
print('World')
class MultiprocessingTest:
def say_process(self, say_type):
h = Hello()
while True:
if hasattr(h, say_type):
result = getattr(h, say_type)()
print(result)
time.sleep(1)
def report(self):
Process(target=self.say_process('say_hello')).start()
Process(target=self.say_process('say_world')).start() # This line hasn't been executed.
if __name__ == '__main__':
t = MultiprocessingTest()
t.report()
The parameter target expects a reference to a function as value but your code passes None to it. These are the necessary parts to change:
class Hello:
def say_hello(self):
while True:
print('Hello')
time.sleep(1)
def say_world(self):
while True:
print('World')
time.sleep(1)
class MultiprocessingTest:
def say_process(self, say_type):
h = Hello()
if hasattr(h, say_type):
return getattr(h, say_type) # Return function reference instead of execute function
else:
return None

How do I access data from a python thread

I have a very simple threading example using Python 3.4.2. In this example I am creating a five threads that just returns the character string "Result" and appends it to an array titled thread. In another for loop iterated five times the threads are joined to the term x. I am trying to print the result x, which should yield a list that looks like ['Resut','Result','Result','Result','Result'] but instead the print command only yields the title of the thread and the fact that it is closed. Im obviously misunderstanding how to use threads in python. If someone could provide an example of how to adequately complete this test case I would be very grateful.
import threading
def Thread_Test():
return ("Result")
number = 5
threads = []
for i in range(number):
Result = threading.Thread(target=Thread_Test)
threads.append(Result)
Result.start()
for x in threads:
x.join()
print (x)
There is a difference between creating a thread and trying to get values out of a thread. Generally speaking, you should never try to use return in a thread to provide a value back to its caller. That is not how threads work. When you create a thread object, you have to figure out a different way of get any values calculated in the thread to some other part of your program. The following is a simple example showing how values might be returned using a list.
#! /usr/bin/env python3
import threading
def main():
# Define a few variables including storage for threads and values.
threads_to_create = 5
threads = []
results = []
# Create, start, and store all of the thread objects.
for number in range(threads_to_create):
thread = threading.Thread(target=lambda: results.append(number))
thread.start()
threads.append(thread)
# Ensure all threads are done and show the results.
for thread in threads:
thread.join()
print(results)
if __name__ == '__main__':
main()
If you absolutely insist that you must have the ability to return values from the target of a thread, it is possible to override some methods in threading.Thread using a child class to get the desired behavior. The following shows more advanced usage and demonstrates how multiple methods require a change in case someone desires to inherit from and override the run method of the new class. This code is provided for completeness and probably should not be used.
#! /usr/bin/env python3
import sys as _sys
import threading
def main():
# Define a few variables including storage for threads.
threads_to_create = 5
threads = []
# Create, start, and store all of the thread objects.
for number in range(threads_to_create):
thread = ThreadWithReturn(target=lambda: number)
thread.start()
threads.append(thread)
# Ensure all threads are done and show the results.
print([thread.returned for thread in threads])
class ThreadWithReturn(threading.Thread):
def __init__(self, group=None, target=None, name=None,
args=(), kwargs=None, *, daemon=None):
super().__init__(group, target, name, args, kwargs, daemon=daemon)
self.__value = None
def run(self):
try:
if self._target:
return self._target(*self._args, **self._kwargs)
finally:
del self._target, self._args, self._kwargs
def _bootstrap_inner(self):
try:
self._set_ident()
self._set_tstate_lock()
self._started.set()
with threading._active_limbo_lock:
threading._active[self._ident] = self
del threading._limbo[self]
if threading._trace_hook:
_sys.settrace(threading._trace_hook)
if threading._profile_hook:
threading. _sys.setprofile(threading._profile_hook)
try:
self.__value = True, self.run()
except SystemExit:
pass
except:
exc_type, exc_value, exc_tb = self._exc_info()
self.__value = False, exc_value
if _sys and _sys.stderr is not None:
print("Exception in thread %s:\n%s" %
(self.name, threading._format_exc()), file=_sys.stderr)
elif self._stderr is not None:
try:
print((
"Exception in thread " + self.name +
" (most likely raised during interpreter shutdown):"), file=self._stderr)
print((
"Traceback (most recent call last):"), file=self._stderr)
while exc_tb:
print((
' File "%s", line %s, in %s' %
(exc_tb.tb_frame.f_code.co_filename,
exc_tb.tb_lineno,
exc_tb.tb_frame.f_code.co_name)), file=self._stderr)
exc_tb = exc_tb.tb_next
print(("%s: %s" % (exc_type, exc_value)), file=self._stderr)
finally:
del exc_type, exc_value, exc_tb
finally:
pass
finally:
with threading._active_limbo_lock:
try:
del threading._active[threading.get_ident()]
except:
pass
#property
def returned(self):
if self.__value is None:
self.join()
if self.__value is not None:
valid, value = self.__value
if valid:
return value
raise value
if __name__ == '__main__':
main()
please find the below simple example for queue and threads,
import threading
import Queue
import timeit
q = Queue.Queue()
number = 5
t1 = timeit.default_timer()
# Step1: For example, we are running multiple functions normally
result = []
def fun(x):
result.append(x)
return x
for i in range(number):
fun(i)
print result ," # normal result"
print (timeit.default_timer() - t1)
t2 = timeit.default_timer()
#Step2: by using threads and queue
def fun_thrd(x,q):
q.put(x)
return
for i in range(number):
t1 = threading.Thread(target = fun_thrd, args=(i,q))
t1.start()
t1.join()
thrd_result = []
while True:
if not q.empty():
thrd_result.append(q.get())
else:
break
print thrd_result , "# result with threads involved"
print (timeit.default_timer() - t2)
t3 = timeit.default_timer()
#step :3 if you want thread to be run without depending on the previous thread
threads = []
def fun_thrd_independent(x,q):
q.put(x)
return
def thread_indep(number):
for i in range(number):
t = threading.Thread(target = fun_thrd_independent, args=(i,q))
t.start()
threads.append(t)
thread_indep(5)
for j in threads:
j.join()
thread_indep_result = []
while True:
if not q.empty():
thread_indep_result.append(q.get())
else:
break
print thread_indep_result # result when threads are independent on each other
print (timeit.default_timer() - t3)
output:
[0, 1, 2, 3, 4] # normal result
3.50475311279e-05
[0, 1, 2, 3, 4] # result with threads involved
0.000977039337158
[0, 1, 2, 3, 4] result when threads are independent on each other
0.000933170318604
It will hugely differ according to the scale of the data
Hope this helps, Thanks

multi thread issue in Python

New to Python multi-thread and write such simple program, here is my code and error message, any ideas what is wrong? Thanks.
Using Python 2.7.
import time
import thread
def uploader(threadName):
while True:
time.sleep(5)
print threadName
if __name__ == "__main__":
numOfThreads = 5
try:
i = 0
while i < numOfThreads:
thread.start_new_thread(uploader, ('thread'+str(i)))
i += 1
print 'press any key to exit test'
n=raw_input()
except:
print "Error: unable to start thread"
Unhandled exception in thread started by <pydev_monkey._NewThreadStartupWithTrace instance at 0x10e12c830>
Traceback (most recent call last):
File "/Applications/PyCharm CE.app/Contents/helpers/pydev/pydev_monkey.py", line 521, in __call__
return self.original_func(*self.args, **self.kwargs)
TypeError: uploader() takes exactly 1 argument (7 given)
thanks in advance,
Lin
The args of thread.start_new_thread need to be a tuple. Instead of this:
('thread' + str(i)) # results in a string
Try this for the args:
('thread' + str(i),) # a tuple with a single element
Incidentally, you should check out the threading module, which is a higher-level interface than thread.
In the following, threadName is now a global variable defined towards the top of the program code, then the variable is initialized before the new thread is started with the target being the upload function.
Try this:
import time
import thread
threadName = ''
def uploader():
while True:
time.sleep(5)
print threadName
if __name__ == "__main__":
numOfThreads = 5
try:
i = 0
while i < numOfThreads:
threadName = 'thread' + str(i)
newThread = threading.Thread(target=uploader)
newThread.start()
i += 1
print 'press any key to exit test'
n=raw_input()
except:
print "Error: unable to start thread"

Passing multiple functions to a class method

I have defined TaskTimer Class below and that I would like to execute multiple functions when the event is triggered which may or may not have arguements. I would like to come up with a generic way of doing this. My functions are not being executed and I do not undestand why. Are my arguements in t.start() incorrect?
import System
from System.Timers import (Timer, ElapsedEventArgs)
class TaskTimer(object):
def __init__ (self):
self.timer = Timer ()
self.timer.Enabled = False
self.handlers =[]
def On_Timed_Event (self,source, event):
print 'Event fired', event.SignalTime
for handler in self.handlers:
handler(*self.my_args,**self.kwargs)
def start(self,interval, repeat, *args, **kwargs):
self.repeat = repeat
self.run = True #True if timer is running
self.timer.Interval= interval
self.timer.Enabled = True
self.my_args= args
self.kwargs = kwargs
for x in self.my_args:
self.handlers.append(x)
self.timer.Elapsed += self.On_Timed_Event
def func1(a,b):
print 'function 1. this function does task1'
print '1...1...1...'
return None
def func2(d):
print 'Function 2. This function does something'
print '2...2...2...'
return None
def func3(a,b,c):
print 'function 3. This function does something else'
return None
def main():
t= TaskTimer()
D= {'fun2':'func2', 'arg2':'3'}
t.start(5000,False,func1, func2, func3, a= 1, b=3, c=4, d=D)
if __name__ == '__main__':
main()
I am experimenting so I edited the def_Timed_Event function and func1, func2 and func3 as shown below. I also added print statement to the functions as suggested by #Ewan. Does Python automatically substitute function variables from **self.kwargs?
def On_Timed_Event (self,source, event):
print '\nEvent fired', event.SignalTime
for handler in self.handlers:
print 'length of self.handlers', len(self.handlers)
print 'args', self.my_args
print 'kwargs', self.kwargs
print 'handler', handler
handler(**self.kwargs)
self.handler[handler](**self.kwargs)
def func1(a,b):
print 'function 1. this function does task1'
print 'func1', a,b
print '1...1...1...'
return None
def func2(d):
print 'Function 2. This function does something'
print 'func2', d
print '2...2...2...'
return None
def func3(a,b,c):
print 'function 3. This function does something else'
print 'func3', a,b,c
return None
The code runs inside IronPyhton console.
![IronPython_console][2]
[2]: http://i.stack.imgur.com/vYW0S.jpg
First of all I can see you having trouble with this line:
handler(*self.my_args,**self.kwargs)
As you aren't accepting any extra kwargs in func1, func2 or func3 I would expect to see the following if it was reaching them:
In [1]: def func1(a, b):
...: print(a, b)
...:
In [2]: kwg = {'a':1, 'b':3, 'c':4, 'd':{'fun2':'func2', 'arg2':'3'}}
In [3]: func1(**kwg)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-3-12557b6441ce> in <module>()
----> 1 func1(**kwg)
TypeError: func1() got an unexpected keyword argument 'c'
Personally I'd put some decent logging/debug statements in to find out where your program is getting in your stack.
Is the program completing successfully or are you getting a TraceBack?
What is this designed to do: self.timer.Elapsed += self.On_Timed_Event?
It looks like it's supposed to be adding a time onto your timer.Elapsed value however nothing is returned by self.On_Timed_Event
On_Timed_Event takes 2 parameters (source, event) however you don't seem to be passing them in, this should also cause the program to fail.
Are you seeing Event fired in your stdout or is the program not getting to On_Timed_Event at all? This may show a problem in your System.Timers code.

Categories