Okay, so I've had this really annoying problem where a variable got set locally but then outside of that function reverted to it's old self (in this case None), but at the same time I could manipulate other variables and still can without using the "global" keyword.
I can't provide the real code for this but it goes something like this:
foo = {}
foo_foo = {}
bar = None
def changes_foo():
...do some stuff to foo...
class EditThread(threading.Thread):
def __init__(self):
setup()
def run(self):
for key, value in foo.items():
do_update_task(key, value)
def do_update_task(self, key, value):
...do some editing too foo...
del foo[key]
bar = [key, value]
foo_foo[key] = value
def print_the_bar():
print bar
Please note that all the operations on foo
and foo_foo
works just fine, but bar is still None when I call print_the_bar
, and I've had lots of print statements in my code to verify that bar inside of do_update_task
indeed has the correct values and isn't None.
Could someone please explain to me why it is so?
If you only need to read the value of a global variable in a function, you don't need the global keyword:
x = 3
def f():
print x
If you ever set the value of a global variable, you need the keyword so that you don't create a local variable:
x = 3
def f():
global x
x = 5
f()
print x
When you do things to foo and foo_foo, you're not changing the reference:
foo = {}
foo['key'] = 'stuff'
foo
still refers to the same object as before; it just now contains more data.
bar = ['key', 'value']
This reassigns bar
to refer to a new object (the list with two elements).
However, when that line is encountered inside a function, it creates a local reference bar
unless you say global bar
. In effect, you have two different variables named bar
: the global and the local.
Saying global bar
tells Python to use the global version of bar
rather than creating a new local variable with the same name.
Generally, if you are modifying global variables, you should state global varname
for each one to avoid accidentally creating a local.
Or, you can use a class:
class State(object):
def __init__(self):
self.foo = {}
self.foo_foo = {}
self.bar = None
state = State()
def fn():
state.bar = ['key', 'value']
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With