我正在阅读“python cookbook”从中我知道有些操作会修改分配给名称的对象。因此可能会引起问题。如:
a = [1,2,3]
b = a
b.append(4)
print a, b
[1,2,3,4] [1,2,3,4]
在这种情况下,我应该:
import copy
b = copy.copy(a)
b.append(5)
print a, b
[1,2,3,4] [1,2,3,4,5]
但是,如果我只是为名称指定一个不同的对象,则不会发生任何事情,例如:
a = 'x'
b = a
a = 0
print a,b
0 x
但是我脑子里提出的一个问题是可以在python中直接修改的对象,以及我可以修改它们的功能? (所以当我遇到需要使用这些功能的地方时,我知道是时候使用复制了)
答案 0 :(得分:1)
来自copy module:
的文档Python中的赋值语句不复制对象,它们在目标和对象之间创建绑定。对于可变或包含可变项目的集合,有时需要一个副本,因此可以更改一个副本而不更改另一个副本。
这是一个SO问题,详细解答Mutable vs Immutable types。
顺便说一下,当你有"复合对象(包含其他对象的对象,如列表或类实例)时,你可以使用deepcopy
而不仅仅是copy
"。
答案 1 :(得分:1)
可变性和不变性是一回事,但另一个经常被混淆的是赋值的效果。
如果你这样做
name = value
name
获得(重新)绑定到value
。
所以,如果你这样做
a = 'x'
b = a
a = 0
如果你这样做是一样的
a = []
b = a
a = {}
b
,将第二个对象分配给a
。此处不进行任何修改。
如果您执行b.append(5)
,则在对象上调用方法,这会导致 - 在这种情况下 - 对其进行修改。但是,分配不会导致修改,而是重新分配。
一般
一个例外是所谓的“扩充赋值运算符”,例如+=
,*=
等等。对于可变和不可变对象,它们的行为确实不同:
a += b
与a = a + b
完全相同:创建一个新对象并保留旧对象。a += b
会改变 a
,以便它包含b
,具体取决于语义。 (或者,至少,允许甚至应该这样做。)从这个角度来看,
a = ()
bak = a
a += (1, 2)
bak is a # False
和
b = []
bak = b
b += [1, 2]
bak is b # True
答案 2 :(得分:0)
没有一般方法可以知道对象是否可变,或者如果它是可变的,如何改变它。您只需阅读文档即可查看可用内容。
在基本内置类型中,数字(整数和浮点数),字符串和元组是不可变的。列表,词组和集合是可变的。 (还有frozenset
这是set的不可变版本。)要查看哪些函数可用于改变这些类型,请阅读their documentation。用户定义的类及其实例通常也是可变的。 (但是类可以设置自己的可变性规则,如果需要,可以使它们的实例有效地不变。)
答案 3 :(得分:0)
如果我的记忆很好,那么唯一可变的对象是:
其他每种类型都是immutable,包括: