Method 2 is wrong because you are doing an operation in two steps when it could be done in one. In method 2, you check if the queue is empty, and then later (very soon, but still later), try to get the item. What if you have two threads pulling items from the queue? The get() could still fail with an empty queue. What if an item is added to the queue after you checked that it was empty? These are the sort of tiny windows of opportunity where bugs creep in to concurrent code.
Do it in one step, it’s by far the better choice.
import Queue
q = Queue.Queue()
try:
task = q.get(False)
except Queue.Empty:
# Handle empty queue here
pass
else:
# Handle task here and call q.task_done()
Don’t get hung up on “exceptions should be errors”. Exceptions are simply another channel of communication, use them. Use the “else” clause here to narrow the scope of the exception clause.