Mutable, Immutable... everything is object!
ROBERTO PALACIOS
DevOps Engineer | Cloud Computing | AWS Cloud | 2x AWS Certified | Certiprof Cibersecurity Certified |
Mutability and immutability in Python (and in other programming languages), that the variables can change (mutable) or not (immutable) Can’t you change the content of any variable unless they are "final" (this is more Java)? Yes, being "final" means that the variable is going to be a constant and that it will never change throughout the execution of the program code. Actually the value of the variables by "below" change one and the other not even if it seems that they really change.
Note on the languages to which it applies: Although I will mention examples of Python here, it applies very similarly or exactly the same in most (not to say "all") languages; as in Java, Javascript, PHP, etc.
Before we start, let’s look at a very simple example in Python to discover details:
my_text = "a text"
We can change the value of the variable by adding something else:
my_text = my_text + " and something more"
So when printing the variable per screen:
print(my_text)
it will show:
a text and something more
Seeing that the string value of the miutexto variable can be changed, then I ask you Sting is mutable? Well no, String is Immutable because in RAM has not expanded the previously saved "one text", but has copied it together with the added " and something else" to save completely "one text and something else" on the other side of the RAM, and the variable will point to the last saved value. That is, a String is always going to be created again (immutable) although we believe it is modified (false belief of mutability). Let’s look at this in detail.
IMMUTABLE
The immutable ones are the easiest to use in programming (they are usually the simple types of data: String, Integer, Boolean, etc.) because they do exactly what they are expected to do at any given time, and paradoxically to work like this they are the ones that punish memory the most (they are not optimized to take up less memory when copied, and further degrade the useful life of the memory when written more times).
They work as follows (I suggest that as you read each of the next paragraphs you look at the image below; in the following images you read first from the left the "Python Console" with a green arrow indicating the added line of code, and then the part on the right with the memory and its occupants).
When we declare a variable (in the following image "mi_variable") in Python (or any other programming language) a variable is created in memory in a memory address (in the image it will be saved in the memory address "id: 0"). If then we assign you (the variable is a cursor or pointer that will "point to the memory address of its value") a mutable value, which for this example will be a text (String, in the image "something, something more") and will be created in another memory position (in the image in the memory address "id: 1"); then the previous variable will point to the mutable object containing its value.
EXAMPLE:
if __name__ == "__main__": my_variable_immutable = "something, something more" print("my_variable_immutable (id: {}): {}".format(id(my_variable_immutable), my_variable_immutable)) def my_function(var_de_func): print("var_de_func before return (id: {}): {}".format(id(var_de_func), var_de_func)) var_de_func += ", added" print("var_de_func (id: {}): {}".format(id(var_de_func), var_de_func)) return var_de_func return_of_function = my_function(my_variable_immutable) print("return_of_function (id: {}): {}".format(id(return_of_function),return_of_function)) print("my_variable_immutable after function (id: {}): {}".format(id(my_variable_immutable), my_variable_immutable))
This code print:
my_variable_immutable (id: 48154248): something, something more var_de_func before return (id: 48154248): something, something more var_de_func (id: 52186528): something, something more added return_of_function (id: 52186528): something, something more, added my_variable_immutable after function (id: 48356248): something, something more
MUTABLE
However, mutables are the most "complex" to use in programming (they are usually data structures like: dict, list, etc.) and not only because they are more complex because they are structures that have things, but they tend to mess with the topic of pointers; and paradoxically they are the least harmful to memory (they are written only once and are always reused). It must be said that the mutables are designed so bet, because copying an entire data structure (although it can) would take a long time and would involve using a lot of memory to surely not take advantage of the copy (it is not the same to copy a String object as to copy a list of millions of String objects, then not having needed the copy; it becomes a waste of processor and memory).
EXAMPLE:
if __name__ == "__main__": def my_function(var_of_func): print("var_of_func (id: {}): {}".format(id(var_of_func), var_of_func)) var_of_func += ["added"] print("var_of_func before return (id: {}): {}".format(id(var_of_func), var_of_func)) return var_of_func my_variable_mutable = ["something", "something more"] print("my_variable_mutable (id: {}): {}".format(id(my_variable_mutable), my_variable_mutable)) return_of_function = my_function(my_variable_mutable) print("return_of_function (id: {}): {}".format(id(return_of_function), return_of_function)) print("my_variable_mutable after function (id: {}):\t.\t{}".format(id(my_variable_mutable), my_variable_mutable))
This code print:
my_variable_mutable (id: 52183808): ['something', 'something more'] var_of_func (id: 52183808): ['something', 'something more'] var_of_func before return (id: 52183808): ['something', 'something more', 'added'] return_of_function (id: 52183808): ['something', 'something more', 'added'] my_variable_mutable after function (id: 52183808): ['something', 'something more', 'added']
Python types classified in Immutable and Mutable
Immutable:
- Strings (text)
- Int (Whole Number)
- Float (floating point number)
- Decimal (Decimal Number)
- Complex (Complex)
- Bool (Boolean)
- Tuple (Tuple): Acts as an immutable list as long as its elements are Resumible ("Hashables").
- Frozenset (Frozen Set): Acts as an immutable set as long as its elements are Summary ("Hashables")
- Bytes
- Range (Range)
- None (Null)
Mutables
- List: Supports any type of values
- Dict (Dictionary): Supports only Resume keys ("Hashables") and values of any type
- Set: Supports only Summary Values ("Hashables")
- Bytearray: Among other uses, it can be used as a mutable string.
- Memoryview: Reference to objects
- Class defined by the programmer. For example, if we inherit from Mutablemapping (more information in the Mapping article) we will make our class NOT Summary ("Unhashable"), so it will be mutable.
Master