I have three functions that want to change a global variable and can't combine into one function, the way I know right now is keep define "global" keyword in each functions to be able to access global variable. Is there a better way to do the same thing with out keep redefining the global variable? for example:
def fn1(self):
global NUM
NUM = 1
print "fn1 = ", NUM
def fn2(self):
global NUM
NUM = 2
print "fn2 = ", NUM
def fn3(self):
global NUM
NUM = 3
print "fn3 = ", NUM
NUM = 0
fn1(NUM)
fn2(NUM)
fn3(NUM)
Thank you
Why don't you define another function, which changes the value of the global variable with the argument provided as parameter. And call this in rest of your function. For example :
var=None
class A:
def change(self,num):
global var
var = num
def first(self,num):
self.change(num)
def second(self,num):
self.change(num)
def third(self,num):
self.change(num)
a=A()
a.first(1)
print 'value of global variable',var
a.second(2)
print 'value of global variable',var
a.third(3)
print 'value of global variable',var
Otherwise, if the scope of your global variable is supposed to be confined within your class then declare it as a member of the class, and let the functions change it's value. For example :
class A:
def __init__(self):
self.var=None
print "default = ", self.var
def first(self,num):
self.var=num
print "fn1 = ", self.var
def second(self,num):
self.var=num
print "fn2 = ", self.var
def third(self,num):
self.var=num
print "fn3 = ", self.var
a=A()
a.first(1)
print 'value of variable',a.var
a.second(2)
print 'value of variable',a.var
a.third(3)
print 'value of variable',a.va
You can make the global variable a mutable class and then mutate in place.
global_dict = {"data": 1}
global_list = [1]
class MutableInt:
def __init__(self, value=1):
self.value = value
global_int = MutableInt()
This works, but personally I wouldn't call that any better. With the global it is at least 100% clear that you change a global variable. Best would be to change your architecture to not need any global variables.
it seems like the function are part of a class , based on the self keyword , if so they all can access class variable without the need of global keyword, if they are not part of a class you can:
define each function with a given parameter to the function and make that function return a value.
def func1(param_1):
#work on param_1
return param_1
Related
Could you help explain why it doesn't work and how to make it work?
class test():
var1 = 0
def subfunc(self):
global var1
if var1 == 0:
print(var1)
test().subfunc()
Then the error is
NameError: name 'var1' is not defined
Let's breakdown your code by parts
class test():
var1 = 0 # class variable 1
def subfunc(self):
global var1 # global variable 2
if var1 == 0: # trigger errors 3
print(var1)
test().subfunc()
This is a class variable, it stays with class, if you update it, you update for all the object that is under this class.
# if outside the class
class test():
var1 = 0 # class variable
test.var1 += 1
# if inside the class
class test():
var1 = 0
#classmethod
def increment_var1(cls):
# it updates the class variable when called
cls.var1 += 1
def some_func1(self):
self.increment_var1()
This is a global variable. In another words, this is outside your class scope and can be shared by another class if they are under the same scope.
If there is a global variable defined in your module, it will reference that global variable and update.
# variable already exists
c = 0 # global variable
def add():
global c # it references the global variable above
c += 2
print(c)
# variable doesn't exists already, it will create a new global variable.
def no_meaning():
global c
c = 0
if var1 == 0:
print(var1)
You encounter error because you don't assign a value to the global variable, so it doesn't have a value to reference to.
Conclusion:
If you want to update a class variable, you should update it by the referencing from class.
If this is a global variable, you should create it on the top of your file. This is very confusing to use the same name with the class variable, so this is advisable to use a different name.
If you want the variable stick with your instance, you should create it from __init__ function
SHARED_VAR = 0
# global variable
class S():
def increment(self):
global SHARED_VAR
SHARED_VAR += 1
# class variable
class C():
var = 0 # class variable
#classmethod
def increment(cls): # only update class variable
cls.var += 1
def instance_increment(self): # only update instance variable
self.var += 1
# instance variable
class I():
def __init__(self, var):
self.var = 0
def increment(self):
self.var += 1
You don't use global for a variable defined within a class, which means it is an instance variable.
The correct way to use this is:
class test():
var1 = 0
def subfunc(self):
if self.var1 == 0:
print(self.var1)
test().subfunc()
I want to access the variable number_of_messages in class A but I get "number_of_messages" is not defined error even though I used global keyword. Here is a code sample:
class A:
number_of_messages=0;
def inc(self):
global number_of_messages
number_of_messages+=1
print(A().inc())
Use the class attribute instead:
class A:
def ___init__(self):
self.number_of_messages=0
def inc(self):
self.number_of_messages+=1
a = A()
print(a.inc())
print(a.number_of_messages)
but you can also:
number_of_messages = 0
class A():
def inc(self):
global number_of_messages
number_of_messages+=1
a = A()
a.inc()
print(number_of_messages)
you just forgot to declare the variable in the global scope
That's not a global. That's a class attribute. Write
def inc(self):
A.number_of_messages += 1
You don't need the global statement.
I need to add a variable "a" to global variables at runtime and be able to recover it anytime from the Item class. Result: I can't see it in the global variables.
Below there is an example. When I print the globals() I don't find the new "a" variable.
Specifically I need to be able to save the printVal result in a variable called "a", which I can consult in next call to this function.
In my final program I plan to add as many different variables as I want (variable and value).
Example:
class Item():
def printVal(self,value):
return value
def func(self):
userInput = input("Input string:")
if userInput!="0":
exec("a=self.printVal(\""+userInput+"\")",globals(),locals())
else:
return
print(globals())
self.func()
if __name__ == "__main__":
item = Item()
item.func()
If you jus watn to set a global variable with a name generated at runtime you do:
globals()[name] = val
by the way printVal method is dummy. Just return whtat it gets.
Below is the code
import os
class ABC:
def test(self,name):
var = 5
var2 = 10
dic = {"Ada": "adada"}
print "asdfdsadv"
var1 = "Ada"
var2 = "asada"
obj = ABC()
print obj.test("Ada").var1
I am looking for something like this. Can I achieve this in python
I know this is var variable in local to class. Is there someway by using global or something else to acheive this
Accessing a variable from a class method is not possible, you have to set the variable at the class level like this:
import os
class ABC:
def test(self,name):
var = 5
var2 = 10
dic = {"Ada": "adada"}
print "asdfdsadv"
self.var1 = "Ada"
var2 = "asada"
obj = ABC()
obj.test('Ada')
print obj.var1
You could chain obj.test('Ada').var1 in the same line by returning self into your test method.
I think this would work. The init(self) behave like a constructor in other languages. So in effect I am constructing a class in a class, to make your last line work properly. But like other suggested that is not the way Python is supposed to be used.
import os
class ABC(object):
def __init__(self):
pass
class test(object):
def __init__(self,name):
self.var = 5
self.var2 = 10
self.dic = {"Ada": "adada"}
print ("asdfdsadv")
self.var1 = "Ada"
self.var2 = "asada"
if __name__ == "__main__":
obj = ABC()
print (obj.test("Ada").var1)
What you are looking for are the class variables, usually defined as self.variable. Here an example of your code:
import os
class ABC:
def __init__(self):
self.var = 5
self.var2 = 10
self.dic = {"Ada": "adada"}
self.var1 = "Ada"
def test(self,name):
print self.var
print self.var2
print self.var1 + " " + name
obj = ABC()
print obj.dic # {'Ada': 'adada'}
print obj.dic["Ada"] # adada
obj.test("wow") # 5, 10, Ada wow
obj.var1 = "Ede"
obj.test("wow") # 5, 10, Ede wow
but as suggested in other answers, you may want to take a step back and check what is the scope of python variables
Forget about classes and consider functions in general.
When you define a function, any variables within its scope are local and only accessible from within the execution of that function. Once execution has finished, that's it, they are gone. This is fundamental; the only way of getting data from a function is by returning it.
Although it is a hack, you could return locals() (a dictionary of local variables), but this is terrible practice.
import os
class ABC:
def test(self,name):
var = 5
var2 = 10
dic = {"Ada": "adada"}
print "asdfdsadv"
var1 = "Ada"
var2 = "asada"
return locals()
obj = ABC()
print obj.test("Ada")["var1"]
If you return the object itself from the function and the variables are not local but instance variables it works.
class ABC:
def test(self, name):
self.var1 = "My name is {}".format(name)
return self
obj = ABC()
print obj.test('Ada').var1
I'm making a python app and I have a class with a function that changes a variable created after the class. I can't put that variable before the class because that variable refers to variables inside the class and I end up with a paradox. It looks something like this:
class LeClass:
def __init__(self):
#Casual__init__Stuff
def LeFunction(self):
A = 1
A = LeClass()
Anyone got a solution? Thanks!
Declare the variable A global before assigning it from within your class code:
global A
A = 1
Otherwise, A will be a local variable that goes out of scope (is not accessible anymore) after the method returns.
Just tell python to look for the variable outside the class first when you try to use that variable.
Here is the code :
class LeClass:
def __init__(self):
pass
#Casual__init__Stuff
def LeFunction(self):
global A
A = 1
A = LeClass()
print("First Print :", A)
A.LeFunction()
print("Second Print :", A)
And here is the output of the code :
First Print : <__main__.LeClass object at 0x7f2ba3f1bb38>
Second Print : 1