0

Possible Duplicate:
“Least Astonishment” in Python: The Mutable Default Argument

I was just playing around with python and stumbled upon something that confuses me.

Why does t1 and t2 in the code below share the same decision dictionary? I have to write

t1=Decision({},txt1="Test1",txt2="Response Test1")

instead of

t1=Decision(txt1="Test1",txt2="Response Test1")

for them to have one each. Why?

I use Python 2.7 if that is of any importance.

class Decision(object):
    def __init__(self,decisions={},txt1="",txt2=""):
        self.decisions=decisions
        self.txt1=txt1
        self.txt2=txt2
    def run(self):
        if len(self.decisions)>0:
            print self.txt1
            print self.txt2
            for i in self.decisions: print i + " - " + self.decisions[i][0]
            ans=""
            while True:
                ans=raw_input("Enter answer: ")
                if ans in self.decisions: break
            if self.decisions[ans][1] is not None: self.decisions[ans][1].run()


t1=Decision(txt1="Test1",txt2="Response Test1")
t2=Decision(txt1="Test2",txt2="Response Test2")    

t1.decisions["yes1"]=("Yes","t2")
t1.decisions["no1"]=("No","t3")

t2.decisions["yes2"]=("Yes","t3")
t2.decisions["no2"]=("No","t1")

print t1.decisions
<<<{'no2': ('No', 't1'), 'no1': ('No', 't3'), 'yes1': ('Yes', 't2'), 'yes2': ('Yes', 't3')}
print t2.decisions
<<<{'no2': ('No', 't1'), 'no1': ('No', 't3'), 'yes1': ('Yes', 't2'), 'yes2': ('Yes', 't3')}

By the way. I solved it by doing this:

class Decision(object):
    def __init__(self,decisions=None,txt1="",txt2=""):
        if decisions==None:self.decisions={}
        else:self.decisions=decisions
        ...

But I would like to know why. Easier to remember not to do it when I now why I shouldn't.

Community
  • 1
  • 1
kimg85
  • 113
  • 1
  • 2
  • 7

1 Answers1

1

Because the def(inition) line that creates the empty dict is evaluated at the time the method is defined, not the time the method is called.

Russell Borogove
  • 18,516
  • 4
  • 43
  • 50