Why is `self` in Python objects immutable?

Any simple assignment to any argument of any function behaves exactly the same way in Python: binds that name to a different value, and does nothing else whatsoever. “No special case is special enough to break the rules”, as the Zen of Python says!-)

So, far from it being odd (that simply=assigning to a specific argument in a specific function has no externally visible effect whatsoever), it would be utterly astonishing if this specific case worked in any other way, just because of the names of the function and argument in question.

Should you ever want to make a class that constructs an object of a different type than itself, such behavior is of course quite possible — but it’s obtained by overriding the special method __new__, not __init__:

class Test(object):
    def __new__(cls):
        return 5

t = Test()
print t

This does emit 5. The __new__ / __init__ behavior in Python is an example of the “two-step construction” design pattern: the “constructor” proper is __new__ (it builds and returns a (normally uninitialized) object (normally a new one of the type/class in question); __init__ is the “initializer” which properly initializes the new object.

This allows, for example, the construction of objects that are immutable once constructed: in this case everything must be done in __new__, before the immutable object is constructed, since, given that the object is immutable, __init__ cannot mutate it in order to initialize it.

Leave a Comment