我试图理解Python中不变性的概念,因为它适用于元组。请考虑以下代码及其输出:
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
输出:140440567920328 140440567920328
正如你所看到的,尽管元组保留了相同的标识,但内容已经改变,即两个列表,一个整数和一个双精度。我知道类似的问题已经在Stack Overflow上无休止地讨论了,但是我想知道如果我们允许在它上面设置一个C ++角度,以下关于元组的思考方式是否正确。
上面代码中的元组是否可以基本上被认为是 跟随struct,去除所有构造函数,析构函数
和其他方法 struct Python_Tuple_Cppform
{
vector<int>* const viptr;
vector<char>* const vcptr;
}
通过在内存中的某处创建向量来指定viptr
和vcptr
的值后,无法更改其值。他们是
将永久指向内存中的相同位置。
然而,这些指针指向的向量的内容可以肯定地被改变,例如, (*viptr).push_back(4)
或(*vcptr).push_back('d')
。这可以解释明显的“悖论”
上面的Python代码。元组不知道是否有内容
它有,正在改变与否。
所以,从这个意义上讲,元组被认为是不可变的,对吧?
修改
正如murgatroid99所建议的那样,A [0]和A [1]之前和之后的ids 追加是一样的。
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])
输出:
140485800073984 140485800079440
140485800073984 140485800079440
答案 0 :(得分:1)
您的分析是正确的。
Python对象总是由指针引用。元组的内容不能变异,但其内容只是指针;你仍然可以改变这些指针指向的对象,如果这些对象允许的话。
正如评论者所指出的,测试理论的一种方法是在id(A[0])
来电之前和之后检查append
。你会发现它仍然是一样的。