Inexplicable behavior in simple example of a set in a class

Chris Rebert clp2 at
Sun Jul 3 01:25:45 CEST 2011

On Sat, Jul 2, 2011 at 3:23 PM, Saqib Ali <saqib.ali.75 at> 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):
>> # 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 `` and `` refer to the same value.

However, if we then do: = 42

then we'll have: == 42 and == 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:
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

Further reading:


More information about the Python-list mailing list