gridproquo
gridproquo

Reputation: 129

Python global vs local variables?

I'm having trouble understanding why my code works the way it does. Right now, I'm initializing a global variable i set to 0, so it makes sense that if I print it anywhere outside my function, I should get 0.

When I print i inside the function, I get 6 and 12 after calling the function twice. I think this is because the global i is 0, but some local i variable isn't. However, when I'm calling reach_load with i as a parameter, aren't I passing in the global value of i (0)?

import sys

d = {}
size_0 = sys.getsizeof(d)
i = 0

def reach_load(d, size_0, i):
    size_0 = sys.getsizeof(d)
    while size_0 == sys.getsizeof(d):
        d[i] = i
        i += 1
    print(i)

reach_load(d, size_0, i)
reach_load(d, size_0, i)

Upvotes: 0

Views: 433

Answers (4)

VlB
VlB

Reputation: 46

When you call i in your function at line 10, in d[i], the Python interpreter you're using first checks for that variable in the local scope. If it doesn't find it, it then checks in the next scope, which in your case happens to be the global one. At this point, you are calling the global variable.

However, as soon as you do i += 1, i becomes a local variable since it's now defined in the local scope.

I'm not 100% on what you expect to happen, though. Are you wondering why the second run of the function returns different results? If so, I believe your problem lies with your size_0 variable.

You define size_0 globally, but at the very start of your function, re-define it locally and that's the definition your function ends up using while the global size_0 ends up not being used at all. If you were to remove:

size_0 = sys.getsizeof(d)

from your function, each run would produce the same result.

What really helps to figure out these issues is adding various code that helps track the execution of your code. In this example, you could add a bunch of print() statements at critical points, such as print(d, size_0) # inside and outside the function.

It's difficult to give anymore advice as it's not clear to me what the code is supposed to accomplish.

Upvotes: 0

Keith
Keith

Reputation: 43024

Because the i parameter to reach_load is a formal parameter it's local to the function. It's a local variable with the same label. If you really want to increment the global one, then put global i it the top of the function. However, this is considered bad design. If you need to keep some state define a new object with class to keep it.

Upvotes: 0

L3viathan
L3viathan

Reputation: 27283

I think you've confused two things here: The global i doesn't change, but d does (as it's mutable). i starts off as 0 each time you call reach_load, but since the dictionary is bigger, the while loop will run longer and therefore, a higher number will be printed.

Upvotes: 0

Daniel Roseman
Daniel Roseman

Reputation: 599600

i is a purely local variable here. It is not linked to the global variable of the same name; the fact that you've called it the same thing makes no difference.

Upvotes: 1

Related Questions