我试图用Python完成一些事情,但我无法在互联网上找到关于此的信息,所以这是我的问题。
拥有此示例代码:
a = 5
b = [a]
我需要b [0]作为a的指针引用。目前如果我做
b[0] = 7
a.var仍然是5,如果我将值设置为b [0],则保持不变。
我想知道Python中是否有任何方法可以在不复制数据的情况下将Object存储在数组中,所以如果我修改了一个,我也会修改另一个。
编辑一个
我想更清楚地说明我想要完成的事情,也许我能找到真正的答案。
我有一个像
这样的自定义类class Foo(object):
def __init__(self):
self.var = 7
我还有一个这样的列表:
myList = [Foo()]
我真正的问题在于:
在代码的某个地方,我需要做以下任务:
self.foo = myList[0]
然后,当我尝试访问此foo var时,我注意到它从未从原始实例更新。基本上这就是我需要的。
编辑两个
所有答案都是正确的。在我的赋值的每一步使用id(var)我可以验证Object始终是相同的,因此错误必须在其他地方。感谢所有人的帮助,我希望这篇文章可以帮助其他人。
答案 0 :(得分:5)
您已经存储了对象,即整数5.您未存储的是名称a
和值5
之间的名称 - 值绑定。您的问题是操作b[0] = 7
不会修改对象5
;它只修改b[0]
与其值(从5到7)之间的绑定,保持值本身(5和7)不受影响。实际上,你不能修改值5,因为5是一个整数,Python中的整数是不可变的。
另一种说法是b[0] = 7
不会修改b[0]
引用的对象;相反,它修改了b
引用的对象。 b
是一个列表,列表是内部跟踪其索引所指向的对象的对象。当你执行b[0] = 7
时,这会告诉b
"在这个新对象"上设置你的0索引点。它没有"通知" b[0]
现在指向它们的5(旧值)或7(新值)。 Python中的对象不知道哪种引用指向它们;他们只知道他们指的是什么(如果有的话)。
您要求的不是存储对象的方式,而是存储"变量" ---即本地命名空间中的名称与值之间的绑定。答案是,通常没有办法在Python中执行此操作。没有任何构造允许你b = something(a)
,所以当你以后做b[0] = 8
时,会改变。
如果您希望能够修改名称 - 值绑定,则需要更改a
,使其成为可以更改其内容的某种对象,而不是仅仅使其成为普通变量。例如,如果你这样做:
a = [5]
b = a
b[0] = 7
然后你会发现a
也发生了变化。对于其他类型的对象也是如此:如果将a
设置为其属性可以更改的其他类型的对象,然后您就地更改其属性,那么这些更改将显示出来你如何引用这个对象。
您可能会发现阅读Python变量的工作方式很有帮助,例如在this article和this one中。
答案 1 :(得分:3)
您是否可以执行此操作取决于您的列表元素是否为immutable or mutable types。不可变类型无法更改,因此当您重新分配一个不可变的变量时,它实际上会创建一个新对象并使用相同的标签对其进行标记。可以更改可变类型,因此可以在不重新分配基础对象的情况下更改它。
例如,假设a
是一个列表,这是一个可变类型。
a = [5]
b = [a]
a[0] = 3
print(b)
# [[3]]
a.append('hi')
print(b)
# [[3, 'hi']]
您的测试代码实际上以您希望的方式运行,因为objects are mutable。
class Object():
pass
a = Object()
a.var = 5
b = [a]
b[0].var = 7
print(a.var)
# 7
出于同样的原因,您的其他示例代码仍然可以正常工作。当我指定a = l[0]
时,它不会复制任何内容,而只是为a
引用的对象创建附加引用l[0]
。
l = [Object() for _ in range(5)]
l[0].var = 5
a = l[0]
l[0].var = 7
print(a.var)
# 7
答案 2 :(得分:1)
你写
a = 5
b = [a]
我需要b [0]作为指向。
的指针
你做不到。您可以使a
指向可变对象并更改该对象的值:
class Object(object):
'''an object'''
a = Object()
a.value = 5
b = a
b.value = 7
现在a.value
返回:
7
同样,但这次有一个清单:
a = [5]
b = a
b[0] = 7
现在a[0]
是:
7