0
def h(y):
    x = x + 1

x  = 5
h(x)
print(x)

So this is from the MIT 6.00.1 course. This bit of code throws an UnboundedLocalError: local variable 'x' referenced before assignment.

I even tried doing this like this:

x = 5
def h(y):
    x = x + 1

h(x)
print(x)

But that also gives the UnboundLocalError. My thought process was that declaring x = 5 before the function is created and placed into the global stack (sorry if the lingo is wrong) would ensure that when we call h(x) the globally scoped variable x would have a value to pass to the function.

I'm also curious that this somewhat similar snippet of code does NOT produce the UnboundLocalError:

x = 12
def g(x):
    x = x + 1
    return x

g(x)

And I am running these code snippets through Python Tutor, I (am fairly sure) that I generally understand the order in which things are occurring as the code executes.

Sorry, and thanks in advance - I am looking to understand what's really going on here instead of glossing over it. I realize that usually locally scoped variables are less confusing and less likely to cause weird bugs.

Anthony
  • 330
  • 3
  • 13
  • 1
    If a variable is assigned to anywhere in a function's body, and there no `global` statement in the function body, that variable is local. That's the whole rule. it doesn't matter if there's a global with the same name, even if three other functions use that global; if you assign to it in this function, it's local in this function. (The only tricky bit is what counts as "assign"—things like `as` clauses, parameters, etc. But don't worry about that right now.) – abarnert Jul 12 '18 at 00:39
  • Actually, when I said don't worry about things like parameters… that's actually what your final question is about. When you do `def g(x):`, you've made `x` a parameter in the `g` function. It doesn't matter that there's a global with the same name; parameters are local variables. And they get assigned to the argument values passed in. So, when you do `g(x)`, referring to the global `x` with value `12`, the local `x` inside `g` gets the value `12`. – abarnert Jul 12 '18 at 00:43
  • Ah. I'm sorry to say but I don't feel that addressed my question. I'm having a hard time understanding why the first code snippet (the `h(y)` function) I provided is throwing the `UnboundLocalError`. Why doesn't the function just take the global value of `x` and feed that to to the function to use as a value of x. That's what I'm not understanding. – Anthony Jul 12 '18 at 02:17
  • 1
    I think everything you're asking is explained in the answers to that question. Again: the rule is that if you have an `x =` in that function, `x` is a local variable in that function, so all references to `x` are to that local variable. That's why Python doesn't load the global variable of the same name, because the reference is to the local variable. Other answers explain how that's implemented in CPython (the compiler sees the assignment when building the symbol table, so when it emits bytecode for `x` it uses `LOAD_FAST` instead of `LOAD_NAME`), and even some of the design rationale. – abarnert Jul 12 '18 at 05:46

0 Answers0