On Sat, Jul 2, 2011 at 3:23 PM, Saqib Ali <saqib.ali...@gmail.com> wrote: >> Instance variables are properly created in the __init__() >> initializer method, *not* directly in the class body. >> >> Your class would be correctly rewritten as: >> >> class MyClass2(object): >> def __init__(self): >> self.mySet = sets.Set(range(1,10)) >> >> def clearSet(self): >> # ...rest same as before... > > > Thanks Chris. That was certainly very helpful!! > > So just out of curiosity, why does it work as I had expected when the > member contains an integer, but not when the member contains a set?
To explain that, one must first understand that name lookup on an object looks in the following places, in order: 1. the instance itself 2. the instance's class 3. the instance's superclasses So, if we have: class Foo(object): bar = 7 foo_inst = Foo() then both `foo_inst.bar` and `Foo.bar` refer to the same value. However, if we then do: foo_inst.bar = 42 then we'll have: foo_inst.bar == 42 and Foo.bar == 7 Now back to your actual question. In clearNum(), you do: self.myNum = 0 which creates a *new* instance variable that shadows the class variable of the same name, like in my example. If you check, you'll indeed see that myClass1.myNum is still 9 after calling clearNum(). By contrast, in clearSet() you do: self.mySet.clear() which just mutates the existing Set object in-place. No new variable is created, and mySet is still a class variable and thus shared by all instances. Further reading: http://effbot.org/zone/python-objects.htm http://effbot.org/zone/call-by-object.htm Cheers, Chris -- http://rebertia.com -- http://mail.python.org/mailman/listinfo/python-list