0

I have a question that is sort of a problem.

I am making a crafting program to learn python more but came across a problem; I assign my variables at the start and user them later like you are supposed to, however it came up with an error message 'UnboundLocalError: local variable 'vSaplings' referenced before assignment'. I tried many different ways of writing it but in the end, all I had to do was change

vSaplings

to

v_Saplings

Now there is no error. Why did this need to be done? It's just a character being added.

Code in question:

vSaplings = 20
...
elif reqO == "Twigs":
        print("This requires at least 1 sapling.")
        if vSaplings > 0:
            amountSaplings = input("How many saplings would you like to use to craft twigs? 1 sapling = 3 twigs.")

This gets the error. Changing 'vSaplings' to 'v_Saplings' removes the error. Why?

Thank you.

EDIT: I now understand that it actually needs to be a global variable. Just 1 more question then, do I need to make my variables global in every single function I create? That seems like it would take up a lot of space.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • 2
    `vSaplings` and `v_Saplings` are two different variables. I think we'll need more context. Are you saying that you changed *both* instances of that name, or just one or the other? – Ian McLaird Sep 19 '15 at 17:06
  • Sorry. Yes I changed both and it worked. –  Sep 19 '15 at 17:06
  • `UnboundLocalError: local variable 'vSaplings' referenced before assignment` -> Do you have v_Saplings anywhere else in that file? – NightShadeQueen Sep 19 '15 at 17:08
  • Change them both back, make no other changes. Does it fail again? (I'm predicting it will still work, and the problem was something else / somewhere else) – TessellatingHeckler Sep 19 '15 at 17:09
  • possible duplicate of [python UnboundLocalError: local variable referenced before assignment](http://stackoverflow.com/questions/15367760/python-unboundlocalerror-local-variable-referenced-before-assignment) – shx2 Sep 19 '15 at 17:10
  • 1
    Is the code that's accessing `vSaplings` in a function, while the initial definition is at the top level? If so, is some other code in the function assigning to `vSaplings`? That will cause an error, as the local variable hides the global variable. You can fix that with a `global` statement, or using a different name if the conflict is accidental. – Blckknght Sep 19 '15 at 17:13
  • My guess is that you have a *third* place (probably inside a function) where you use that variable name. Remember that functions that use a variable name that's defined at the global scope must declare their intent to do so by saying `global vSaplings` (in this case). – Ian McLaird Sep 19 '15 at 17:18
  • Yes I have that variable elsewhere. Blckknght you are right, how do I make it a global variable then? I tried global vSaplings but then I cannot assign a value to it. –  Sep 19 '15 at 17:18
  • Does this answer your question? [UnboundLocalError trying to use a variable (supposed to be global) that is (re)assigned (even after first use)](https://stackoverflow.com/questions/370357/unboundlocalerror-trying-to-use-a-variable-supposed-to-be-global-that-is-rea) – Karl Knechtel Feb 06 '23 at 12:57

1 Answers1

0

You've done something like this:

#This will NOT work
foo = 20

def f():
    if foo > 10:
        print 'hello'
    foo = foo + 1

This will trigger the Unbound local error.

To work around it, you can do one of a couple of things. The simplest is something like this:

#This is OK
foo = 20

def f():
    global foo
    if foo > 10:
        print 'hello'
    foo = foo + 1

However, as a general rule, you should work to avoid global variables. There are a host of reasons for this, most of which boil down to "it makes the code harder to understand and maintain. It's easier to reason about self-contained functions, and so you might consider doing something more like this:

#Better (in the opinion of this poster)

def f(foo):
    if foo > 10:
        print 'hello'
    return foo + 1

Which could then be called from anywhere like this:

foo = f(foo)
Community
  • 1
  • 1
Ian McLaird
  • 5,507
  • 2
  • 22
  • 31