简体   繁体   中英

About the immutability of Python tuples

I am trying to understand the concept of immutability in Python, as it applies to tuples. Consider the following code and its output:

A = ([1,2,3],['a','b','c'])
print id(A)
A[0].append(4)
A[1].append('d')
print id(A) # Prints the same id as the previous id(A) call even after contents are modified

Output: 140440567920328 140440567920328

As you can see, although the tuple retains the same identity, the contents have changed ie two lists, one of integers and one of doubles. I know similar questions have been discussed endlessly on Stack Overflow, but what I wanted to know if the following way of thinking about tuples is correct, if we are allowed to put a C++ angle on it.

Could the tuple in the above code be essentially considered as the following struct, stripped of all the constructors, destructors and other methods as

 struct Python_Tuple_Cppform
 {
   vector<int>* const  viptr;
   vector<char>* const vcptr;
 }

Once the values of viptr and vcptr have been assigned by creating vectors somewhere in memory, their values cannot be changed. They are will permanently point to the same place in memory.

However, the contents of the vectors these pointers point to can most certainly be changed eg (*viptr).push_back(4) or (*vcptr).push_back('d') . This would explain the apparent 'paradox' of the Python code above. The tuple does not 'know' whether the contents it has, are being changed or not.

And so, it is in this sense that the tuple is considered immutable, right?

EDIT

As suggested by murgatroid99 the ids of A[0] and A[1] before and after the append are the same.

A = ([1,2,3],['a','b','c'])
print id(A[0]), ' ' , id(A[1])
A[0].append(4)
A[1].append('d')
print id(A[0]), ' ' , id(A[1])

Output:

140485800073984 140485800079440

140485800073984 140485800079440

Your analysis is correct.

Python objects are always referred to by pointer. The contents of a tuple cannot be mutated, but its contents are just pointers; you can still mutate the objects that these pointers point to, if those objects allow it.

As a commenter points out, one way to test your theory would be to check id(A[0]) before and after the append calls. You would find that it remains the same.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM