两个python对象具有相同的id,但是“ is”操作返回false,如下所示:
a = np.arange(12).reshape(2, -1)
c = a.reshape(12, 1)
print("id(c.data)", id(c.data))
print("id(a.data)", id(a.data))
print(c.data is a.data)
print(id(c.data) == id(a.data))
这是实际输出:
id(c.data) 241233112
id(a.data) 241233112
False
True
我的问题是...为什么“ c.data是a.data”即使它们指向相同的ID也指向相同的对象却返回false?我以为如果它们具有相同的ID,则它们指向相同的对象,或者我错了吗?谢谢!
答案 0 :(得分:16)
a.data
和c.data
都产生一个 transient 对象,但没有对其进行引用。这样,两者都会立即被垃圾收集。两者可以使用相同的ID。
在您的第一个if
语句中,对象必须共存,而is
则检查它们是否相同。
在第二个if
语句中,id
一旦返回其ID,就会释放每个对象。
如果保存对两个对象的引用,并使它们保持活动状态,则可以看到它们不是同一对象。
r0 = a.data
r1 = c.data
assert r0 is not r1
答案 1 :(得分:6)
In [62]: a = np.arange(12).reshape(2,-1)
...: c = a.reshape(12,1)
.data
返回一个memoryview
对象。 id
仅给出该对象的ID;它不是对象的值,也不是a
数据缓冲区所在位置的任何指示。
In [63]: a.data
Out[63]: <memory at 0x7f672d1101f8>
In [64]: c.data
Out[64]: <memory at 0x7f672d1103a8>
In [65]: type(a.data)
Out[65]: memoryview
https://docs.python.org/3/library/stdtypes.html#memoryview
如果您想验证a
和c
共享一个数据缓冲区,我发现__array_interface__
是一个更好的工具。
In [66]: a.__array_interface__['data']
Out[66]: (50988640, False)
In [67]: c.__array_interface__['data']
Out[67]: (50988640, False)
它甚至显示切片产生的偏移量-这里是24字节,3 * 8
In [68]: c[3:].__array_interface__['data']
Out[68]: (50988664, False)
我还没有看到a.data
的大量使用。当使用buffer
创建新数组时,它可用作ndarray
对象:
In [70]: d = np.ndarray((2,6), dtype=a.dtype, buffer=a.data)
In [71]: d
Out[71]:
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11]])
In [72]: d.__array_interface__['data']
Out[72]: (50988640, False)
但是通常我们会使用切片或np.array
(copy = False)创建具有共享内存的新阵列。