0

When I use two global dictionaries (in my case, Counters) that interact, Python throws a local reference error. To illustrate the issue, here is sample code:

from collections import Counter

hourly_detections = Counter()
daily_detections = Counter()

def populate_hourly():
    hourly_detections['cat'] += 1
    hourly_detections['dog'] += 2
    hourly_detections['mouse'] += 3

def populate_daily():
    daily_detections += hourly_detections

def run():
    populate_hourly()
    populate_daily()

    print(hourly_detections)
    print(daily_detections)

if __name__ == '__main__':
    run()

This code throws the following error within the populate_daily function: UnboundLocalError: local variable 'daily_detections' referenced before assignment

However, if we add the global flag specifically for daily_detections in the populate_daily function, the code runs flawlessly:

from collections import Counter

hourly_detections = Counter()
daily_detections = Counter()

def populate_hourly():
    hourly_detections['cat'] += 1
    hourly_detections['dog'] += 2
    hourly_detections['mouse'] += 3

def populate_daily():
    global daily_detections
    daily_detections += hourly_detections

def run():
    populate_hourly()
    populate_daily()

    print(hourly_detections)
    print(daily_detections)

if __name__ == '__main__':
    run()

The output is:

Counter({'mouse': 3, 'dog': 2, 'cat': 1})

Counter({'mouse': 3, 'dog': 2, 'cat': 1})

Can anyone explain this behavior and how best to avoid it?

Austin
  • 802
  • 11
  • 20

1 Answers1

2

don't forget to use global daily_detections and global hourly_detections at each function.

Python thinks these are local variables unless you declare them as globals at the beginning of the function, and then after you are trying to do hourly_detections['cat'] += 1 you are basically trying to add one to "a non initialized variable"

You may also send them if you want as function parameters as it is considered better practice (please read here).

snatchysquid
  • 1,283
  • 9
  • 24
  • Before I accept, can you help me understand why I don't get the same error within the populate_hourly function? I don't make any mention of global there. It only occures within populate_daily. – Austin Jun 04 '20 at 14:51
  • 1
    I added a before (at the end) explaining that using global variables inside functions is bad because it causes a lot of confusion and misunderstandings. If you don't use `global variable_name` it doesn't know what to think: is it global or is it local? In this case it managed to understand (probably has something to do with the `["word"]`) that `hourly_detections` is global but didn't in the daily one. Anyway it is very bad practice and you should either pass it as an argument or put `global` everywhere and not rely on the compiler and assume it will understand. – snatchysquid Jun 04 '20 at 15:20