我读到python中的assign不复制它的工作方式就像它在c中指定一个指向对象的指针一样。
但是当我调试这个函数时:
def popall(self):
objs = self.curstack
self.curstack = []
return objs
看起来某种副本正在发生。在此功能运行后,obis充满了各种东西, self.curstack
是空的......
所以正在进行一些复制。是深还是浅?
答案 0 :(得分:4)
它不会复制任何东西。只是分配给self.curstack
并不会修改用于引用的self.curstack
。只是让self.curstack
引用其他内容。
这样想。 self.curstack
指向一些东西。使用objs = self.curstack
,您objs
指向相同的内容。使用self.curstack = []
,您可以将self.curstack
指向一个空列表。这并不能删除self.curstack
过去指出的任何内容;那些东西还在那里,objs
仍指着它。
This article使用标签标签的一个很好的类比来解释它。
答案 1 :(得分:2)
Python在任何地方都使用引用。所以你的代码就像这样:
objs = self.curstack
现在objs
指向任何curstack
。
self.curstack = []
现在curstack
指向一个空列表。 objs
未更改,并指向旧curstack
。
return objs
您返回objs
,这是旧版curstack
。
答案 2 :(得分:2)
正如self.curstack
未对其进行修改的所有答案所述,只需提及某些内容即可。在你的情况下,它指的是一个空列表[]
。
您实际上可以使用swampy
查看对象的引用方式 from swampy.Lumpy import Lumpy
class ref_test:
def __init__(self, curstack):
self.curstack = curstack
def popall(self):
lampy = Lumpy()
objs = self.curstack
self.curstack = []
print id(self.curstack), id(objs)
lampy.object_diagram()
return objs
o = ref_test([1,2,3,4])
res = o.popall()
print res
正如您所看到的,self.curstack
指向一个空列表,而objs
仍然保留了self.curstack
的旧值。
您可以使用id函数来检查对象的“身份”。对于self.curstack
和objs
164711692 163838732
答案 3 :(得分:0)
让我们演示一下究竟发生了什么(使用显示内存位置的id
)
a = [1,2,3]
print id(a)
b = a
print id(b)
a = 4
print id(a)
print a
print b
4339130240
4339130240
4298163184
4
[1,2,3]
因此a
和b
最初指向内存中的相同位置,但随后a
指向某个新位置。但是现在,让我们试试
a = [1,2,3]
print id(a)
b = a
print id(b)
a[0] = 4
print id(a)
print a
print b
4339098040
4339098040
4339098040
[4,2,3]
[4,2,3]
所以b
不是a
的全新副本。它与a
(当它被定义时)是同一个对象。如果你那么a=4
,你告诉python,让我们忘记a
过去指向的内容并为其赋予新的含义。 4不会出现在a
用于引用的内存中。相反,a
现在指的是记忆中的新位置。 b
仍然指的是a
最初提到的内容。
如果我们不重新分配a
,而是更改a
指向的对象中的某个内容,则检查b
会显示相应的更改发生在{ {1}}。
答案 4 :(得分:0)
在Python中,有两个空格,命名空间和对象空间。
名称只是您分配给对象的标签,它们位于对象空间中。对象具有值和类型;名字只是为了我们的方便;这样我们就可以访问对象空间中的东西。
这与C之类的其他语言不同,其中变量更像是一个盒子,你可以放置某种类型的东西。
在Python中,名称可以指向任何类型的任何对象 - 它们只是别名。
为对象指定名称时,如下所示:
a = 1
a
只是一个标签,指向具有类型(int)和值的对象1
。如果你接下来这样做:
b = 1
现在您有两个名称a
和b
指向同一个对象 - 它们不是"副本",而只是两个标签指向同一个对象。
执行此操作时:
a = 'hello'
现在a
指向一个新对象,但b
仍然指向旧对象(1
)。
最终,当没有名称指向对象时,Python会自动进行垃圾回收以保持对象空间的优化。