12

So basically I have no idea what is wrong with this small piece of code, and it seems like I can't find a way to make it work.

points = 0

def test():
    addpoint = raw_input ("type ""add"" to add a point")
    if addpoint == "add":
        points = points + 1
    else:
        print "asd"
    return;
test()

The error I get is:

UnboundLocalError: local variable 'points' referenced before assignment

Note: I can't place the "points = 0" inside the function, because I will repeat it many times, so it would always set the points back to 0 first. I am completely stuck, any help would be appreciated!

gromiczek
  • 2,970
  • 5
  • 28
  • 49
Errno
  • 187
  • 1
  • 1
  • 11

3 Answers3

32

points is not within the function's scope. You can grab a reference to the variable by using nonlocal:

points = 0
def test():
    nonlocal points
    points += 1

If points inside test() should refer to the outermost (module) scope, use global:

points = 0
def test():
    global points
    points += 1
user2722968
  • 13,636
  • 2
  • 46
  • 67
  • +1 for `nonlocal`, though I favour Xeun's solution. –  Sep 19 '13 at 12:05
  • When defining that first test() function, I get a Syntax Error: no binding for nonlocal 'points' found, even though I already defined points = 0, as you did above. 'global' worked, but not the 'nonlocal'. – alexGIS Oct 17 '19 at 21:48
8

You could also pass points to the function: Small example:

def test(points):
    addpoint = raw_input ("type ""add"" to add a point")
    if addpoint == "add":
        points = points + 1
    else:
        print "asd"
    return points;
if __name__ == '__main__':
    points = 0
    for i in range(10):
        points = test(points)
        print points
Xeun
  • 1,089
  • 1
  • 11
  • 20
  • 1
    This is the proper design pattern, and should be the selected answer, as it fixes the root of the problem instead of creating a work around for a poorly designed function. – alexGIS Oct 17 '19 at 21:49
0

Move points into test:

def test():
    points = 0
    addpoint = raw_input ("type ""add"" to add a point")
    ...

or use global statement, but it is bad practice. But better way it move points to parameters:

def test(points=0):
    addpoint = raw_input ("type ""add"" to add a point")
    ...
Michael Kazarian
  • 4,376
  • 1
  • 21
  • 25
  • 2
    As I said in the question, I can't move it into test because it would set it back to 0 everytime I called test(), but thanks for the answer – Errno Sep 19 '13 at 12:01