Python Global Variables - Not Defined?
Solution 1
You have to use global df
inside the function that needs to modify the global variable. Otherwise (if writing to it), you are creating a local scoped variable of the same name inside the function and your changes won't be reflected in the global one.
p = "bla"
def func():
print("print from func:", p) # works, readonly access, prints global one
def func1():
try:
print("print from func:", p) # error, python does not know you mean the global one
p = 22 # because function overrides global with local name
except UnboundLocalError as unb:
print(unb)
def func2():
global p
p = "blubb" # modifies the global p
print(p)
func()
func1()
print(p)
func2()
print(p)
Output:
bla # global
print from func: bla # readonly global
local variable 'p' referenced before assignment # same named local var confusion
bla # global
blubb # changed global
Solution 2
You have to use the global
keyword inside the function rather than outside. All the df
that you have defined inside your function are locally scoped. Here is the right way -
df = pd.DataFrame() # No need to use global here
def __init__(self, master):
global df # declare here
df = None
....
def load(self):
global df # declare here
....
df = pd.read_csv(filepath)
def save(self):
global df # declare here
....
df = df.append(...)
Solution 3
for anyone coming here using python3 - try using nonlocal instead of global - a new construct introduced in python3 which allows you to mutate and read global variables in local scope
Axioms
Updated on December 28, 2021Comments
-
Axioms over 2 years
I'm running into an issue where a global variable isn't "remembered" after it's modified in 2 different functions. The variable
df
is supposed to be a data frame, and it doesn't point to anything until the user loads in the right file. This is similar to something I have (usingpandas
andtkinter
):global df class World: def __init__(self, master): df = None .... def load(self): .... df = pd.read_csv(filepath) def save(self): .... df = df.append(...)
save()
is always called afterload()
. Thing is, when I callsave()
, I get the error that "df
is not defined." I thoughtdf
got its initial assignment ininit()
, and then got "updated" inload()
? What am I doing wrong here? -
Axioms about 6 yearsOh, so do I need to declare it every time I need to call it? There isn't a way for it to be "universally" remembered inside a class?
-
Osman Mesut Ozcan about 6 years@Axioms if you want it to be available for all functions in a class you can make it a class variable. Other than that nothing much to do but to write it in every function needed
-
Patrick Artner about 6 years@Axioms I prefer to not use globals at all - I mostly provide them as parameters to functions or put them as member variables inside classes.
-
Axioms about 6 yearsSo if I set
x = "hello"
right after I declare a class (i.e. class variable), then would thatx
be"hello"
in every function of that class? -
Patrick Artner about 6 years@Axioms That would be a "static" Class-Variable, its shared between instances of that class, one changes it - all gets the change. Unless you need to create 20 different worlds, accessing the same
df
I would probably use aself.df = None
inside the__init__(self, ... )
, load it inside loadself.df = pd.read_csv(...)
etc. -
Axioms about 6 yearsAh, guess I was confusing global variables with class variables. Got it, thank you.