2

I am writing an application in Python that relies heavily on global list variables. Each function in the program applies a change to one or all of these global lists. While coding, I found that I required several functions involving movements of elements between the global lists, all of which involved the same lines of code--so I wrote an appropriate functor class.

The program below summarizes what I am doing. I will reference it to describe the problem occurring in my application:

#Global List variables
garbage=[]
paper=[]
metal=None

class movementFunctor:
    def __init__(self,source,destination):
        self.source=source
        self.destination=destination
    def __call__(self,item):
        self.source.remove(item)
        self.destination.append(item)

GtoP=movementFunctor(garbage,paper)
GtoM=movementFunctor(garbage,metal)
PtoM=movementFunctor(paper,metal)

def main():
    global garbage,paper,metal
    metal=[]
    #initialize garbage, paper, and plastic with numbers 0 to 5
    for i in range(5):
        garbage.append(i)
        paper.append(i)
        metal.append(i)
    GtoP(2)

    #Problem Code---------------------------------------------------------------------
    PtoM(2)
    #Problem Code---------------------------------------------------------------------
main()

My functor class, movementFunctor, specifies a source global variable list and a destination global variable list as parameters for instance variables. Then, the call operator specifies the movement of an item from the source list to the destination.

I thought this design would be successful; however, I have reached an error in the line 'PtoM(2)'

line 11, in __call__self.destination.append(item)
AttributeError: 'NoneType' object has no attribute 'append'

One of the global lists, metal, was initialized to None, but main should have assigned it a new empty list []. So why would the PtoM functor run to the problem of metal being declared as None, when it was assigned the empty list?

I cannot find any information online or from previous posts regarding problems/intricacies of setting global variables as instance variables for a class.

I am new to the Stack Overflow forum, so please forgive/point out any conventions I have not followed well in posting this question.

1 Answers1

3

You created your PtoM before calling main. At that time, metal was None, so PtoM set its destination to None. It does not "watch" the variable metal to see if something else was assigned.

The solution is to either assign metal = [] at the beginning, or move the creation of your PtoM and others inside main, after metal is set.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • Beat me to it :). I would also add a link to [this question](http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference) regarding parameter passing in python. – J0HN Jul 02 '14 at 05:37
  • That link really clarifies how variables work. I have learned a lot from it, and I see that my problem stems from this misunderstanding of pass by value and pass by reference in Python. – user3796200 Jul 02 '14 at 20:55