Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument
Okay, so basically I have this code:
# Our Rule type.
class Rule(object):
"""An object to represent a rule and include
methods to apply these rules."""
def __init__(self,bind="F",rule=["F"]):
self.bind = bind
self.rule = rule
def show(self):
try:
print self.bind
#print self.rule
for i in range(len(self.rule)):
print self.rule[i]
except:
print "Incomplete"
def inflate(self,seq):
for i in range(len(seq)):
if seq[i] == self.bind:
seq[i] = self.rule
elif type(seq) == type(["X"]):
seq[i] = self.inflate(seq[i])
return seq
def inflate_depth(self,seq,depth):
while depth > 0:
seq = self.inflate(seq)
depth = depth - 1
print self.rule
return seq
I call it from another file with this code:
pity = Rule(rule=["R","F","L","F","L","F","R","F"])
seq = ["F"]
inf = pity.inflate_depth(seq,2)
So, I should end up with a list that looks like this:
[['R', [...], 'L', [...], 'L', [...], 'R', [...]]]
Which seems to work fine, but there is one fundamental error.
self.rule
has been altered to contain ['R', [...], 'L', [...], 'L', [...], 'R', [...]]
Why? There is no where whatsoever I assign a new value to that variable, but it changes nonetheless.
I’m not 100% sure about this but I suspect the problem is that variables in Python are references and not values. That is to say, when you set
seq[i] = self.rule,seq[i]points to whereself.ruleis stored in memory and any changes made toseq[i]‘s value results in a change toself.rulesince their values are stored at the same location in memory.What you probably should do is deep copy
self.rule‘s value intoseq[i]rather than simply assign it so that they use two different memory addresses to store their values (see http://docs.python.org/library/copy.html for more information), that way assigning toseq[i]won’t affectself.rule.