列出指向行为python

时间:2016-04-26 12:45:44

标签: python list python-2.7

我需要一些帮助来更好地理解python中的list如何在内部处理它所指向的对象。

我将用情况解释我的疑问。好吧,我们走了。

让我们想象一下,我创建了一个名为Foo的类,我把它的一些实例放在一个列表中,如下所示:

class Foo(object):
  def __init__():
    ...
    ...

foo1 = FOO()
foo2 = FOO()
l = [foo1,foo2]

根据我的理解,que list指向实例对象foo1和foo2。我想这意味着我在实例对象中直接执行的任何更改都将在列表中完成,反之亦然,这完全是预期的,因为列表和变量foo1和foo2指向相同的实例对象。这很好,意味着我可以用这种方式对这个实例对象进行更改:

for foo in l:   
  perform_some_changes(foo)

eval(foo1); eval(foo2); eval(l[0]); eval(l[1])

使用eval()函数,我会看到for循环中执行的更改在变量和列表中保持不变。再一次,一切都如预期。

鉴于上述情况,我的问题是:为什么,如果不是使用用户创建的实例对象,我使用的是float()内置数据类型的int(),它也是对象(因为,python中的所有内容)是对象),列表不会保持相同的行为?同样,我将用相同的代码解释我的意思:

a = 0
b = 0
l = [a,b]
for el in l:
  for i in range(5):
    el+=1
print a # zero
print b # zero
print l # zero

在上面显示的情况中,f​​or循环中执行的更改不会在变量和列表中保留。然而,由于刚刚讨论的内容,这对我来说很有意义。对我来说,循环中执行的更改应该保留在变量和列表中,sinse应该指向同一个地址。我错过了什么吗?是这样,在这种情况下,我怎么能使所有内容指向同一地址而不创建新实例。

感谢您的进步。

2 个答案:

答案 0 :(得分:3)

在Python中有可变不可变数据类型(此列表不一定完整):

  • <强>可变

    • listŠ
    • dict ionaries
    • setŠ
    • 自定义object s
  • <强>不可改变:

    • 基本数字数据类型,例如intfloatboollongcomplex
    • str英格斯
    • tupleŠ
    • frozensetŠ

现在可变类型与其他语言中存储在堆上的引用数据类型类似,而不可变类型更像值数据类型直接存储在堆栈内存中。

您可以操纵可变数据类型的实例。引用旧对象的所有变量名仍引用新对象,因为它是相同的实例。

相反,您无法操纵不可变数据类型。当您执行似乎操作它们的任何操作时,它们会返回实例的新修改副本。原始实例保持不变,仍然被之前指向它的所有变量名称引用。但是,新的修改后的实例仅由您为其指定的变量名称引用。它不再与旧实例相关。

总结一下:

您可以就地修改可变对象,对它们的所有引用都会反映这些更改。

不可变的数据类型可能无法修改,尝试时总会得到一个新实例。所有其他引用将保持绑定到旧实例,并且不受“操作”的影响。

答案 1 :(得分:1)

Python中的数字是不可变的,因此+ = operation会创建新的int对象并对其进行列表元素引用,而变量引用旧对象。