-4

I followed a queue example from the bottom of the Python Queue page. I want to access some global variables within the worker function, however, some globals are accessible and some aren't. In my simple example below, the 'rows' and 'errors' variables are accessible but then I get UnboundLocalError for count. If i put "global count" then it works. But I don't understand why the other globals are accessible.

File "myfile.py", line 184, in dpn_worker
    count += 1
UnboundLocalError: local variable 'count' referenced before assignment

Here is the code example I used:

dpns = [1,2,3,4]
q = Queue.Queue()
rows = []
errors = []
count = 0

def dpn_worker():
    while True:
        item = q.get()
        rows.append(1)
        errors.append(1)
        count += 1
        q.task_done()

def main():
    for d in dpns:
        q.put(d)

    for i in range(NUM_WORKERS):
        t = threading.Thread(target=dpn_worker)
        t.daemon = True
        t.start()

    q.join()
trinth
  • 5,919
  • 9
  • 40
  • 45
  • 3
    Pasting the question title into the search box gives http://stackoverflow.com/q/9264763/395760 as very first result. Is a tiny bit of research really that hard? -1 –  Oct 04 '12 at 17:12
  • Sorry, I actually did search at first. Guess my google-fu failed me this time. – trinth Oct 04 '12 at 17:28

1 Answers1

2

In this case, since count is an integer: -

count += 1

is equivalent to

count = count + 1

So, you are trying to modify the global variable, but are actually creating a local one.. But on the RHS, you are using the local variable before initialization..

Modify your dpn_worker as: -

def dpn_worker():
    global count
    while True:
        item = q.get()
        rows.append(1)
        errors.append(1)
        count += 1
        q.task_done()
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • 2
    Nope, it's not precisely equivalent. In-place addition can have, and in the case of some collections, has different semantics from "regular" addition. –  Oct 04 '12 at 17:13
  • @delnan.. OK.. Is it defined somewhere, in what condition they are different?? Actually I have started coding in Python just a few days back.. – Rohit Jain Oct 04 '12 at 17:17
  • 1
    @RohitJain one example can be lists, for lists `+=` works as `extend()` and `lis =lis +somelis` actually creates a new list(`lis+somelis`) and then assigns it to `lis` on the LHS. – Ashwini Chaudhary Oct 04 '12 at 17:19
  • @AshwiniChaudhary.. Then what happens to the original list in second case?? Garbage Collected? – Rohit Jain Oct 04 '12 at 17:21
  • 2
    @RohitJain Potentially, but it could have other names, which would still contain the original list. If you did ``a = [1, 2]`` then ``b = a``, then ``a = a + [3]``, ``a`` would be ``[1, 2, 3]`` while ``b`` would be ``[1, 2]``. If you did ``a += [3]``, both would be ``[1, 2, 3]``. – Gareth Latty Oct 04 '12 at 17:21
  • @Lattyware.. Yeah that is what we call `Reference Count`.. – Rohit Jain Oct 04 '12 at 17:22
  • if it's refcount is 0 then yes it is GC. – Ashwini Chaudhary Oct 04 '12 at 17:22
  • @RohitJain I know, I was just specifying that it was the case - it is not safe to assume that it will be garbage collected. For one, in some other implementation, it could not happen for any reason (as Python doesn't specify how garbage collection should be done) and that other references could still exist. This can be a gotcha. – Gareth Latty Oct 04 '12 at 17:23
  • Yeah.. That is somewhat similar to Java.. Of course, garbage collection is completely out of our control.. Thanks @Lattyware... :) – Rohit Jain Oct 04 '12 at 17:25
  • @Lattyware.. One more question.. What book should I refer for Python?? – Rohit Jain Oct 04 '12 at 17:26
  • @RohitJain python even caches strings and small integers, which you may not find in Java. For books you can try http://www.quora.com/What-is-the-best-book-for-learning-Python-as-a-beginner and http://www.quora.com/Python-programming-language-1/What-are-the-best-books-for-learning-Python – Ashwini Chaudhary Oct 04 '12 at 17:29
  • @AshwiniChaudhary.. Thanks for the link.. Actually, Java also caches string literals, and integer till some range, which is different on different JVMs. – Rohit Jain Oct 04 '12 at 17:31
  • @AshwiniChaudhary. Actually that list I have seen on many websites, but couldn't decide which one to grab... Currently I have started reading `Core Python Programming`.. – Rohit Jain Oct 04 '12 at 17:33
  • @RohitJain I learned from `core python programmming `too and also `learning python`(mark lutz). But I learned about most of the cool and advanced stuff on SO itself. – Ashwini Chaudhary Oct 04 '12 at 17:40
  • 1
    @AshwiniChaudhary.. Yeah you're right.. There is lot to learn on SO.. Thanks :) – Rohit Jain Oct 04 '12 at 17:41