2
counter = 0
def addCounter():
 counter = counter + 1
 return counter

UnboundLocalError: local variable 'counter' referenced before assignment.

I'm trying to make a counter count every time this function runs. I've tried passing the counter variable in as a parameter as well, but that doesn't work either.

s3dev
9,8693 gold badges34 silver badges49 bronze badges
asked Jan 21, 2020 at 8:25
4
  • you should use global counter Commented Jan 21, 2020 at 8:28
  • 2
    Another option is to wrap the function in a class, and have counter as a class variable - which will be accessible to all functions in the class. Commented Jan 21, 2020 at 8:29
  • 2
    Definitely preferable to use a class and class variables over globals. Commented Jan 21, 2020 at 8:31
  • 1
    Does this answer your question? Function not changing global variable Commented Jan 21, 2020 at 8:34

2 Answers 2

4

You need:

counter = 0
def addCounter():
 global counter
 counter = counter + 1
 return counter

Explanation: in Python, the declaration of inner variables is implicit, an assignment automatically declares the values on the left-hand side, however that declaration is always in the local scope. That's why if you write this:

counter = 0
def addCounter():
 return counter

it will work fine but as soon as you add an assignment

counter = 0
def addCounter():
 counter += 1
 return counter

it breaks: the assigment adds an implicit local declaration. global overrides this, although it requires that the global exist beforehand, it does not create a global, it just tells the function that this is a global variable it can reassign to.

I've tried passing the counter variable in as a parameter as well, but that doesn't work either.

Indeed not. Python's evaluation strategy is sometimes called "pass by sharing" (or "pass reference by value") which is technically "pass by value" but that term gets a bit confusing as the values in this case are references, the references are copied but the objects referred to are not, and thus the end-behaviour diverges from the normal expectations of "pass by value" expectations.

Masklinn
43.8k4 gold badges58 silver badges78 bronze badges
answered Jan 21, 2020 at 8:27
Sign up to request clarification or add additional context in comments.

1 Comment

Python syntax allows this 'shortcut' (if you like). counter += 1
2

Using a class rather than global:

Another way to handle (not use) global variables is to wrap the functions and variables you wish to be global in a class.

While this is a little heavy for this specific case - classes add a host of functionality and flexability to the project. (Personally) highly recommended.

For example:

class Processor():
 """Class container for processing stuff."""
 _counter = 0
 def addcounter(self):
 """Increment the counter."""
 # Some code here ...
 self._counter += 1
# See the counter incrementing.
proc = Processor()
proc.addcounter()
print(proc._counter)
proc.addcounter()
print(proc._counter)

Output:

1
2
answered Jan 21, 2020 at 8:36

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.