Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I think immutable types like frozenset and tuple not actually copied. What is this called? Does it have any implications?

I was messing around while trying to figure out shallow and deep copying in Python, and noticed that while the identities of a copied set, list, or seemingly any mutable type aren't the same:

In[2]: x1 = {1,2,3}
In[3]: x2 = x1.copy()
In[4]: x1 is x2
Out[4]: False

For immutable types this isn't the case - it looks like a copy points to the same address in memory.

In[6]: f1 = frozenset({1,2,3})
In[7]: f2 = f1.copy()
In[8]: f1 is f2
Out[8]: True

This sort of intuitively makes sense to me - why would you need two identical immutable objects in memory anyways. But I've never seen it before - is there a name for this process? Is it done for speed purposes?

Furthermore, are there any implications of this "not actual copying"? I'm not convinced there are but I want to be sure - the only thing I could come up with is if someone decided to modify mutable types inside an immutable type, which from what I know would be a bad idea anyways.

In[11]: t1 = tuple((1, ['a', 'b']))
In[12]: t2 = tuple(t1) # I would expect an actual copy, but it is not
In[13]: t1[1].append('c')
In[14]: t2
Out[14]: (1, ['a', 'b', 'c'])
like image 550
Eric Hansen Avatar asked May 08 '16 14:05

Eric Hansen


People also ask

What does it mean when a tuple is immutable?

We often call lists mutable (meaning they can be changed) and tuples immutable (meaning they cannot be changed).

Is Frozenset immutable in Python?

Python frozenset() Method creates an immutable Set object from an iterable. It is a built-in Python function. As it is a set object therefore we cannot have duplicate values in the frozenset.

Why tuples are called immutable in Python?

Immutability of Tuple Tuples are immutable and hence cannot have any changes in them once they are created in Python. This is because they support the same sequence operations as strings. We all know that strings are immutable. The index operator will select an element from a tuple just like in a string.

What is a Frozenset data type in Python?

Frozen set is just an immutable version of a Python set object. While elements of a set can be modified at any time, elements of the frozen set remain the same after creation. Due to this, frozen sets can be used as keys in Dictionary or as elements of another set.


1 Answers

It's called polymorphism.

Different types can implement the __copy__() and __deepcopy__() hooks and do something different that makes sense to their type. The copy module simply calls those hooks to delegate the actual copy work (or in the case of the set types, you delegate to the set.copy() method). Immutable types then are free to return self to avoid wasting memory.

Otherwise, there is no special name for the choice to return self from __copy__() for immutable types.

Note that for the tuple-with-list example, you only asked for a shallow copy. Shallow copies of containers always re-use the references to the contents. The same thing would happen with list(some_list_object) or dict(some_dict_object). Use a deep copy instead to ensure that you get a tuple with a copy of the contained list; a new tuple object is then created too:

>>> import copy
>>> t1 = (1, ['a', 'b'])
>>> t2 = copy.deepcopy(t1)
>>> t1 is t2
False
>>> t1[0].append('c')
>>> t2
(1, ['a', 'b'])
like image 109
Martijn Pieters Avatar answered Nov 14 '22 18:11

Martijn Pieters