如何在python中为对象引用指定None



我是python的新手,对以下代码的输出有点困惑。

class obj:
def __init__(self, data):
self.data = data
o1 = obj(2)
o2 = o1
def func1(obj):
obj.data = 5

func1(o1)
print(o1.data)
print(o2.data)
o2 = None
print(o1)
print(o2)

输出:

5
5
<__main__.obj instance at 0x7f7f6b5e63f8>
None

o1对象不应该也变成"无"吗??

o1不应该是None

当执行行o2 = None时,o2不再引用o1对象。现在它指的是None对象。o1o2现在引用内存中的两个不同对象,如id函数所示(不同的标识,id返回CPython中的对象内存地址(

print (id(o1)) # 140282748479024
print (id(o2)) # 140282748479024
o2 = None
print (id(o1)) # 140282748479024
print (id(o2)) # 140282774063376

Python中的变量是对象的名称,而不是C++中的内存位置。重新分配一个名称只会改变名称所指的内容;它不会更改referent或其他别名。


最接近的等价物是指针:在CPython中,像o2 = o1那样指定名称实际上意味着PyObject *o2 = *o1。地址被从一个名称复制到另一个名称。赋值后的名称之间没有直接关系——它们只是碰巧仍然引用同一个对象。

>>> o1 = {1, 2, 3}
>>> o2 = o1
>>> print(id(o1), id(o2))  # the *referents* of o1 and o2 are at the same memory location
4444160520 4444160520

当两个名称引用同一个对象时,它们显示对象的相同状态——毕竟,只有一个状态。这就是为什么通过o2也可以看到更改o1.data的原因——o2o1都引用的对象被修改了。

>>> o1.add(16)
>>> print(o1, o2)  # still the same referent, should have the same state
{16, 1, 2, 3} {16, 1, 2, 3}
>>> print(id(o1), id(o2))  # both still have the same referent
4444160520 4444160520

诀窍是,虽然o1o2是分开的,但像o1.datao2.data这样的成员不是!每个顶级名称都是一个单独的实体。然而,属性等是相对于其对象的!


重新分配时,只会更改分配给的名称。请记住,o2o1复制了引用-更改名称o1不会影响任何关系。

>>> o1 = None
>>> print(o1, o2)  # not the same referent anymore
None {16, 1, 2, 3}
>>> print(id(o1), id(o2))  # only o2 still refers to the same referent
4436169032 4444160520

o2 = None有效地重新分配为与o1不同的对象。观察:

>>> o1 = obj(2)
>>> id(o1)
155034832  
>>> o2 = o1
>>> id(o2)
155034832  # same ID as o1
>>> o1 is o2
True       # the objects are identical

但一旦重新分配o2:

>>> o2 = None
>>> id(o2)
262150788  # ID has now changed
>>> o1 is o2
False      # the objects are now different.

一旦重新分配,对象之间就没有任何关系(除非通过其他方式绑定(,合理地说,您不应该期望它们的行为相同。

相关内容

最新更新