Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is `self` in Python objects immutable?

Tags:

python

object

Why can't I perform an action like the following:

class Test(object):     def __init__(self):         self = 5  t = Test() print t 

I would expect it to print 5 since we're overwriting the instance with it, but instead it doesn't do anything at all. Doesn't even throw an error. Just ignores the assignment.

I understand that there would be hardly any situations where one would want to do that, but it still seems odd that you can't.

Update: I now understand why it doesn't work, but I'd still like to know if there is any way of replacing an instance from within the instance.

like image 872
Evan Fosmark Avatar asked Jun 18 '09 22:06

Evan Fosmark


People also ask

Why does Python use immutable objects?

Immutable objects are quicker to access and are expensive to change because it involves the creation of a copy. Whereas mutable objects are easy to change.

Why are numbers in Python immutable?

Security (3), Easy to use (4) and capacity of using numbers as keys in dictionaries (5) are reasons for taken the decision of making numbers immutable. Has fixed memory requirements since creation time (1). All in Python is an object, the numbers (like strings) are "elemental" objects.

Are objects from user defined classes immutable in Python?

The object remains the same, even if you are changing properties of the object. And no, there are only very few immutable objects in python - frozenset for instance. But classes are not immutable. If you want immutable objects, you have to make them so.

What does immutable mean in Python?

Most python objects (booleans, integers, floats, strings, and tuples) are immutable. This means that after you create the object and assign some value to it, you can't modify that value. Definition An immutable object is an object whose value cannot change.


2 Answers

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.

like image 146
Alex Martelli Avatar answered Sep 22 '22 22:09

Alex Martelli


It doesnt "ignore" the assignment. The assignment works just fine, you created a local name that points to the data 5.

If you really want to do what you are doing...

class Test(object):     def __new__(*args):         return 5 
like image 29
mthurlin Avatar answered Sep 22 '22 22:09

mthurlin