Reputation: 5003
Here's a fun one. Create a file foo.py
with the following contents:
OPTIONS = {'x': 0}
def get_option(key):
from foo import OPTIONS
return OPTIONS[key]
if __name__ == '__main__':
OPTIONS['x'] = 1
print("OPTIONS['x'] is %d" % OPTIONS['x'])
print("get_option('x') is %d" % get_option('x'))
Running python foo.py
gives the following output:
OPTIONS['x'] is 1
get_option('x') is 0
I would have expected the result to be 1
in both cases. Why is it 0
in the second case?
Upvotes: 1
Views: 82
Reputation: 3327
You are getting this because from foo import OPTIONS
line in get_options()
function loads a new local OPTIONS variable in a memory whose value is {'x':0}. But if you remove/comment that line, then you got your expected result, this is because as OPTIONS variable in get_options()
is now a global variable, not a local.
OPTIONS = {'x': 0}
def get_option(key):
# from foo import OPTIONS
return OPTIONS[key]
if __name__ == '__main__':
OPTIONS['x'] = 1
print("OPTIONS['x'] is %d" % OPTIONS['x'])
print("get_option('x') is %d" % get_option('x'))
You can also debug that by using the id() function which returns the “identity” of an object during it's lifetime.
For that the debugging code is:
OPTIONS = {'x': 0}
def get_option(key):
from foo import OPTIONS
print("Id is %d in get_option" % id(OPTIONS))
return OPTIONS[key]
if __name__ == '__main__':
OPTIONS['x'] = 1
print("Id is %d in main" % id(OPTIONS))
print("OPTIONS['x'] is %d" % OPTIONS['x'])
print("get_option('x') is %d" % get_option('x'))
Output:
Id is 140051744576688 in main
OPTIONS['x'] is 1
Id is 140051744604240 in get_option
get_option('x') is 0
Note: values of id's can be changed on your system.
Now, you can see the id's is different in both place, this means that there are two OPTIONS inside get_options()
function one is __main__.OPTIONS
and other one is foo.OPTIONS
. But, if comment/remove line from foo import OPTIONS
in get_options()
, you get same id's at both places.
Upvotes: 2