Search code examples
pythonfunctionscopeglobaldeque

Accessing a global deque or data structure from within a function


I have a need to create global deques in a main program and use them in functions called from that program. In my example, I create a deque, "questions", and add two lists to the deque. I print the deque from the main program to show that it was successfully created and populated.

In the function I attempt to pop the items off the deque "questions" and into a variable, "question" but I get a "NameError: global name 'questions' is not defined"

How can I access the deque in the function? The commented out "global questions" and "from collections import deque" have also been tried with the same result and all the permutations of including or excluding those lines.

The function is in a module, and the file structure is as follows:

├── problemmain.py
├── modules
│   ├── problemchild.pyc
│   ├── problemchild.py
│   ├── __init__.pyc
│   └── __init__.py

problemmain.py:

#!/usr/bin/python

# Send them to the id connector
from modules.problemchild import problem_child
from collections import deque
#idconnector_send(questions,\
#                 rmdconfig.idconnector['send_dst_hostname'],\
#                 rmdconfig.idconnector['send_dst_port'])

questions=deque()

questions.append(['item1','item2','item3',['inneritem1','inneritem2','inneritem3','inneritem4','inneritem5','inneritem6']])
questions.append(['item1','item2','item3',['inneritem1','inneritem2','inneritem3','inneritem4','inneritem5','inneritem6']])

print questions

problem_child()

#idconnector_receive(rmdconfig.idconnector['receive_dst_hostname']\
#                    rmdconfig.idconnector['receive_dst_port'])

modules/__init__.py:

#!/usr/bin/python
#__all__ = ["readconf",]

modules/problemchild.py:

#!/usr/bin/python

def problem_child():

    """Determine what's wrong with modules scope and deque
    """
#    from collections import deque
#    global questions
    while True:
            #question = questions.pop()
            question = questions.pop()
            print "Question is: "
            print question
            print "----------------------------------------------------"

Output:

./problemmain.py


deque([['item1', 'item2', 'item3', ['inneritem1', 'inneritem2', 'inneritem3', 'inneritem4', 'inneritem5', 'inneritem6']], ['item1', 'item2', 'item3', ['inneritem1', 'inneritem2', 'inneritem3', 'inneritem4', 'inneritem5', 'inneritem6']]])
Traceback (most recent call last):
  File "./problemmain.py", line 17, in <module>
    problem_child()
  File "/home/justin.h.haynes/rmd/modules/problemchild.py", line 11, in problem_child
    question = questions.pop()
NameError: global name 'questions' is not defined

Trying Aaron's suggestion, and replacing "questions_queue" I get the following:

$ ./problemmain.py
Traceback (most recent call last):
  File "./problemmain.py", line 13, in <module>
    modules.questions_queue=deque()
NameError: name 'modules' is not defined

Solution

  • I would suggest you make questions an explicit argument:

    def problem_child(questions):
    

    and pass it from the caller:

    print questions
    problem_child(questions)
    

    It is generally a bad sign that you feel the need to use global variables.