DEV Community

Discussion on: Mutable Default Arguments in Python

Collapse
 
rhymes profile image
rhymes

Great question! I had to refresh my knowledge a bit about the why

Nice, I see this as a great time to ask though, is there an Object.freeze() equivalent in Python that will automatically let us make mutable objects immutable?

Not really, there are immutable objects like numbers, strings, tuples and frozen sets but a generic object can't be automatically frozen.

You can play with some builtin methods like setattr (which is called when a new attribute is added to an object) and its specular getattribute to create a custom immutable object

And if not, why wouldn't something like that be added?

Probably because the language has immutable data types that are used daily: numbers, strings and tuples.

For example:

>>> a = "abc"
>>> a[0] = "x"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

but in Ruby:

2.7.0 :001 > a = "abc"
2.7.0 :002 > a[0] = "x"
2.7.0 :003 > a
 => "xbc"

if you look at many Ruby code bases, you'll see .freeze used beside many strings that are defined as constant because by default they are mutable. In Python they aren't. I personally prefer the latter design choice.

In 2005 there was a PEP (the name of Python community proposals) to add a freeze() method, called freeze protocol. It was rejected and among the reasons there are the following:

  • the concept of frozen objects in Python is related to them being able to be keys in a dictionary (all immutable objects can be), but why would a dev need an entire object to be a key in a dictionary?

  • sending objects around both in their mutable version and their immutable one can lead to errors. Ruby has a .frozen? method to help you distinguish them, but still, that would mean that each receiver of that object would need to check if the object is frozen or not. It's easier to assume that all objects aside from those immutable builtins are mutable and live with that.

TLDR; language design choices. 15 years have passed since that proposal and Python doesn't seem to be in need of a freeze() method after all