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()
Related
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 want to make it so x is only global within the class.
I have tried using self.x but that does not seem to work. I could be doing it wrong though.
class Test:
def __init__(self):
pass
def test1(self,number):
global x
x = number
print(x)
def whereIwantToRedefineIt(self):
print(x)
Test().test1(2) #<------ Making output 2
x=200 #<-------------- It should not be able to redefine the variable
Test().whereIwantToRedefineIt() #<-------- I want to make this output 2
I want to make the function "whereIwantToRedefineIt" not be affected by the "x=200" which is outside the class. I want it to output 2
class Test:
def __init__(self):
self.x = None
def test1(self,number):
self.x = number
print(x)
def whereIwantToRedefineIt(self):
print(self.x)
You can get the desired result if you invoke the methods on the same instance.
test = Test()
test.test1(2)
test.whereIwantToRedefineIt() # This will print 2
The closest thing is a class variable, which can be accessed by prefixing the variable name with the class name:
class MyClass:
somevar = 0
def somemethod(self):
print(MyClass.somevar)
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 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
I want to keep track via a counter, every time a class is instantiated. I was trying to do this by incrementing a counter defined as a class variable from inside the class' consructor ala:
class Cl:
cntr = 0
def __init__(self):
cntr += 1
However, when I instantiate the class, I get an "UnboundLocalError: local variable 'cntr' referenced before assignement" I'm assuming this is because the constructor is treating it as a local variable. How do I reference the class variable from inside a method or constructor in Python 2.7?
You just have to call the variable through the class:
class Cl:
cntr = 0
def __init__(self):
Cl.cntr += 1 # <---Like this
print(Cl().cntr) # prints 1
print(Cl().cntr) # prints 2
print(Cl().cntr) # prints 3
class Foo:
n = 0
def __init__(self):
self._increment()
#classmethod
def _increment(cls):
cls.n += 1
f1 = Foo()
f2 = Foo()
>>> f1.n
2
>>> f2.n
2