Python threads and global vars - python

Say I have the following function in a module called "firstModule.py":
def calculate():
# addCount value here should be used from the mainModule
a=random.randint(0,5) + addCount
Now I have a different module called "secondModule.py":
def calculate():
# addCount value here too should be used from the mainModule
a=random.randint(10,20) + addCount
I am running a module called "mainModule.py" which has the following (notice the global "addCount" var):
import firstModule
import secondModule
addCount=0
Class MyThread(Thread):
def __init__(self,name):
Thread.__init__(self)
self.name=name
def run(self):
global addCount
if self.name=="firstModule":
firstModule.calculate()
if self.name=="secondModule":
secondModule.calculate()
def main():
the1=MyThread("firstModule");
the2=MyThread("secondModule");
the1.start()
the2.start()
the1.join()
the2.join()
# This part doesn't work:
print firstModule.a
print secondModule.a
Basically I want the "addCount" value in both modules to be the one from "mainModule". After that, when the threads are finished, I want to print the value
of "a" in both of them. The example above doesn't work. I was wondering how can I fix it.

Pass 'addCount' to the function 'calculate', return the value of 'a' in 'calculate', and assign it to a new attribute in MyThread instance.
def calculate(addCount):
a = random.randint(0, 5) + addCount
return a

Modules in python are singletons, so you can put your global variables in module globalModule.py and have both firstModule, secondModule, and mainModule import globalModule and they will all access the same addCount.
However, in general it's a bad practice for threads to have a global state.
This will never work:
print firstModule.a
print secondModule.a
because in here:
def calculate():
# addCount value here should be used from the mainModule
a=random.randint(0,5) + addCount
a is a local variable to the function calculate.
If you really want to write a as a module-level variable, add global declaration:
def calculate():
# addCount value here should be used from the mainModule
global a
a=random.randint(0,5) + addCount

Related

free variable referenced before assignment in enclosing scope

Hey im having some trouble understanding what I did wrong/finding a way to fix it, can you guys help me?
def main():
Keys = 0
def Function1():
global all
def Function2():
global all
print(str(Keys))
Function2()
Keys = Keys + 1
Function1()
main()
every time i try to run this i get this error "free variable 'Keys' referenced before assignment in enclosing scope"
Thanks in advance!
You need to define global Keys for every function. A function thinks that Keys is a local variable.
def main():
global Keys
Keys = 0
def Function1():
global Keys
global all
def Function2():
global Keys
global all
print(str(Keys))
Function2()
Keys = Keys + 1
Function1()
main()
However, using global is bad. Here are a list of reasons why using global is bad
So, instead of using global, you can pass it as an parametre.
def main():
Keys = 0
def Function1(Keys):
def Function2(Keys):
print(str(Keys))
Function2(Keys)
Keys = Keys + 1
Function1(Keys)
main()
Also, all is a function in python. There is absolutely no need to make it global

How to recalculate/reinitialize variables of a class in python

I have some app.py in which I do the following:
Trader = Trader(settings)
while True:
try:
Trader.analyse_buys()
Now I have the following in trader.py
def __init__(self):
self.since = self.calculate_since()
...
def analyse_buys():
dosomething()
So the analyse_buys() will run in a loop without a new calculation of the value since.
What could be a possible solution to recalculate my variables in the __init__ function again before starting the function again?
If you need to still save some state in Trader, i.e. instantiating a new one with
trader = Trader()
isn't an option, consider moving the bits that need to be reinitialized into another function, and calling that both within __init__() and from elsewhere:
class Trader:
def __init__(self):
self.state_that_shouldnt_be_re_prepared = ...
self.prepare() # (or whatever is a sensible name)
def prepare(self):
# do things
# ...
trader = Trader()
while ...:
if something:
trader.prepare()

Issue with global variables in python

I am getting issue with global variable declared in python file.
I do not have class declaration in the file.
i am just declaring some variables in the class with none type.
and modifying that variables in the function.
when i was calling those variables inside another class by importing them,
instead of modified value it is returning None type only.
Below is the code
from selenium import webdriver
from Pages.PageMethods.Google_Methods import Methods
browser = None
s = None
def before_feature(context, feature):
print("before feature")
def before_scenario(context, scenario):
print('before scenario', scenario.name)
context.driver = webdriver.Firefox()
#context.driver.maximize_window()
browser = context.driver
global s
s = Methods(browser)
s.samplemethod()
def after_scenario(context, scenario):
print("after scenario", scenario.name)
context.driver.quit()
def after_feature(context, feature):
print("after feature")
->Here i was calling that 's' variable inside another class,it is returning None type only instead of object for that assigned class
Please someone help
Here is the code that i am calling that variable
from features.environment import *
use_step_matcher("re")
fileConfig('logging.ini')
log = logging.getLogger('sLogger')
#given("i am on google page '(.*)'")
def navigate(context, url1):
context.url = url1
log.info("this is log statement")
context.driver.get(url1)
context.driver.implicitly_wait(10)
#then("I enter value into search box as '(.*)'")
def step_impl(context, text):
print("selector:=>", Google.search_box)
context.driver.find_element(*Google.search_box).send_keys(text)
print("url in second step is:=>", context.url)
time.sleep(1)
s.printtitle()
and i was getting this error:
AttributeError: 'NoneType' object has no attribute 'printtitle'
You need use global operator
example:
global_var = list()
def somefunc():
global global_var
global_var.append(1)
somefunc()
print global_var
out:
[1]

accessing a variable from outside the function in python

#!/usr/bin/env python
import roslib
import rospy
import time
from nav_msgs.msg import Odometry
def position_callback(data):
global q2
q2=data.pose.pose.position.x
q1=data.pose.pose.position.y
q3=data.pose.pose.position.z
def position():
rospy.init_node('position', anonymous=True) #initialize the node"
rospy.Subscriber("odom", Odometry, position_callback)
if __name__ == '__main__':
try:
position()
print q2
rospy.spin()
except rospy.ROSInterruptException: pass
the error i get is like this:
print q2
NameError: global name 'q2' is not defined
I defined q2 as global variable already.
Declaring q2 as a global variable does make the global variable exist.
Actually calling the function and execution of the assignment statement q2 = ... cause the creation of the variable. Until then, the code cannot access the variable.
position function does not call the position_callback, but pass it to rospy.Subscriber (which probably register the callback function, and not call it directly).
Initialize q2 if you want to access the variable before it is set.
q2 = None
def position_callback(data):
global q2
q2 = data.pose.pose.position.x
q1 = data.pose.pose.position.y
q3 = data.pose.pose.position.z
You never initialize q2. It cannot have a value. Try to define it in global scope - after the imports. Then call it iniside the functionposition().

How to access a variable from a class of another module

I am a total python beginner and I have a variable created in a class of a file commandline_reader.py that I want to access from another script. I tried to do it by making the variable global, which doesn't work.
myscript.py:
from commandline_reader import Commandline_Reader
reader = Commandline_Reader('--get_serial_number')
reader.run()
print output
commandline_reader.py:
class Commandline_Reader:
def __init__(self,argString=''):
global output
output = []
def run(self):
# do stuff
a = 'somevariable'
output.append(a)
When I run myscript.py I always get a NameError: name 'output' is not defined. I've read that this is because global variables are only defined within a module. How do I correctly access the output variable in my script?
ouch. The whole reason object oriented programming takes place is to avoid the use of global variables. Make them instance variables to access them anywhere in the class.
class Commandline_Reader:
def __init__(self,argString=''):
self.output = []
def run(self):
# do stuff
a = 'somevariable'
self.output.append(a) #output is now part of the instance Commandline reader and can be accessed anywhere inside the class.
clr = Commandline_Reader(argstring='--get_serial_number')
clr.run()
print clr.output
>>>['somevariable']
Make output an instance attribute:
class Commandline_Reader:
def __init__(self,argString=''):
self.output = [] # note use of self here
def run(self):
# do stuff
a = 'somevariable'
self.output.append(a) # and here
The access it via the instance:
print reader.output
Maybe class attribute is more appropriate for you?
class Commandline_Reader:
output = []
def run(self):
# do stuff
a = 'somevariable'
self.output.append(a)
Just return the Value from the run() Method
myscript.py:
from commandline_reader import Commandline_Reader
reader = Commandline_Reader('--get_serial_number')
output = reader.run()
print output
commandline_reader.py:
class Commandline_Reader:
def __init__(self,argString=''):
self.output = []
def run(self):
# do stuff
a = 'somevariable'
self.output.append(a)
return self.output

Categories

Resources