myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
myVar.append('lololol')
print myTuple
为什么以及如何通过在构造之后附加来修改这个元组?
myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
myVar = "lolol"
print myTuple
为什么要打印([1,2,3], [4,5,6], "lol")
而不是([1,2,3], [4,5,6], "lolol")
?
答案 0 :(得分:7)
好吧,让我试着用一些图片来解释。
在Python中,一切都是对象。这些对象由变量引用。某些类型的对象(如列表和元组)只存储对其他对象的引用。
那说,当你执行
myVar = ["jhhj", "hgc"]
myTuple = ([1,2,3], [4,5,6], myVar)
您或多或少会遇到这种情况:
每个对象由方框/矩形表示。我们有两个字符串对象"jhhj"
和"hgc"
。此外,我们有一个列表对象,由变量myVar
指向;此列表对象指向两个字符串对象。另外,我们有一个由myTuple
引用的元组对象;此元组对象指向另外两个列表和myVar
引用的列表。
执行时
myVar.append('lololol')
会发生什么?好吧,列表对象(偶然由myVar
指出)开始引用另一个值,字符串对象"lololol"
:
请注意myVar
仍引用列表对象。发生的事情是列表对象已更改。您可以从myVar
或从元组中查看此列表对象,您将看到具有相同更改的同一对象。
OTOH,执行时
myVar = "lol"
myTuple = ([1,2,3], [4,5,6], myVar)
你得到这样的东西:
现在myVar
指向字符串对象"lol"
,并且元组在其第三个位置引用它。现在,如果你执行
myVar = "lolol"
你只是让myVar
指向另一个对象。元组对象仍然像以前一样指向"lol"
:
因此,如果将新值归因于变量,则只会更改此变量指向的值。变量引用的先前值仍然存在*,指向它的任何其他变量或对象将保持指向它。只是属性变量会改变。
PS:另外,I answered a vaguely related question some time ago。您可能会发现答案很有用。
*除非它是由垃圾收集器收集的,但这是另一个漫长的历史。
答案 1 :(得分:5)
python中的所有东西都是对象。
所以当你做原始作业时
myVar = "lol"
你给myVar一个对象的引用" lol"
然后创建一个元组。第三个插槽中的这个元组引用了" lol"
然后你创建一个新对象" lolol"并给myVar一个参考。元组保留其对" lol"
的原始引用答案 2 :(得分:1)
元组是不可变的,所以如果你想修改它的一个成员,你需要构造一个新的元组......
答案 3 :(得分:1)
元组是不可变的,但您可以将它们连接在一起,如:
var a = (1, 2)
var b = a + (3, 4)
答案 4 :(得分:1)
在这两种情况下,当您创建元组时,您正在复制对当时myvar
对象的引用。
在第一种情况下,myvar
是一个可变对象。您可以在对象的引用存储在元组中后更改对象。
在第二种情况下,myvar
是一个不可变的字符串。您无法更改对象,但可以更改myvar
本身所指的内容。但这并没有改变元组中包含的对象。
答案 5 :(得分:1)
在其他答案中有一些重点我不会再次重复,解释名称和对象之间的区别。我认为缺少的是当一些Python代码在名称上操作以及在对象上操作时拼写出来。
您需要了解的一件事是,直接影响名称的唯一事物是赋值语句[1]。赋值语句将名称重新绑定以指向其他对象。出现在任何其他上下文中的名称只是在执行该行代码时名称绑定到的任何对象的简单代表。
让我们看看你的例子中的这一行:
myTuple = ([1,2,3], [4,5,6], myVar)
myTuple
出现在赋值语句的左侧,因此名称 myTuple
正在那里受到影响。另一方面,myVar
位于表达式中,因此对象 myVar
被绑定到元组的第三个元素,不名称myVar
。
因此, name myVar
稍后发生的任何事情都不会对元组产生任何影响。但只要元组的第三个元素和myVar
引用相同的对象,更改对象(通过myVar
或元组)将明显影响你得到的内容当你通过参考文件看对象时。
[1]对于高级研究,def
和class
语句也是“赋值语句”(它们创建一个函数或类,然后将其分配给名称)。
此外,像+=
,*=
等运算符有时 赋值语句,有时不是,取决于当前由名称引用的对象的类型LHS:
myList = []
myList += ['this calls a method on a list object which mutates it in place; the name is not changed']
myInt = 1
myInt += 10 # This rebinds myInt to refer to a new object 11; the object 1 is not changed