Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Scoping/Static Misunderstanding

I'm really stuck on why the following code block 1 result in output 1 instead of output 2?

Code block 1:

class FruitContainer:
       def __init__(self,arr=[]):
           self.array = arr
       def addTo(self,something):
           self.array.append(something)
       def __str__(self):
           ret = "["
           for item in self.array:
               ret = "%s%s," % (ret,item)
           return "%s]" % ret

arrayOfFruit = ['apple', 'banana', 'pear']
arrayOfFruitContainers = []

while len(arrayOfFruit) > 0:
   tempFruit = arrayOfFruit.pop(0)
   tempB = FruitContainer()
   tempB.addTo(tempFruit)
   arrayOfFruitContainers.append(tempB)

for container in arrayOfFruitContainers:
   print container 

**Output 1 (actual):**
[apple,banana,pear,]
[apple,banana,pear,]
[apple,banana,pear,]

**Output 2 (desired):**
[apple,]
[banana,]
[pear,]

The goal of this code is to iterate through an array and wrap each in a parent object. This is a reduction of my actual code which adds all apples to a bag of apples and so forth. My guess is that, for some reason, it's either using the same object or acting as if the fruit container uses a static array. I have no idea how to fix this.

like image 965
Raymond Berg Avatar asked Oct 31 '09 17:10

Raymond Berg


1 Answers

You should never use a mutable value (like []) for a default argument to a method. The value is computed once, and then used for every invocation. When you use an empty list as a default value, that same list is used every time the method is invoked without the argument, even as the value is modified by previous function calls.

Do this instead:

def __init__(self,arr=None):
    self.array = arr or []
like image 56
Ned Batchelder Avatar answered Sep 22 '22 00:09

Ned Batchelder