使用零定义arrray a
后,我可以使用以下函数创建最左侧列的视图:
a = np.zeros((5, 5))
a_left_col = a[:, 0]
a_left_col[:] = 2.
打印a
:
array([[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.],
[2., 0., 0., 0., 0.]])
如果我随后使用
重新初始化a
a = np.zeros((5, 5))
然后视图仍然存在,但它不再引用任何内容。如果再次执行a_left_col[:] = 2
,Python如何处理这种情况?这是在C或C ++中的未定义行为,还是Python正确处理它,如果是这样,为什么不抛出错误?
答案 0 :(得分:1)
行为未定义。您只是在创建一个新对象a
。旧的不会被释放,但仍然存在于内存中,因为a_left_col仍然引用它。重新初始化a_left_col
后,可以取消分配原始数组。
答案 1 :(得分:1)
原始对象仍然存在,因为它被视图引用。 (虽然不能再通过变量a
访问它。)
让我们详细了解一下对象的引用计数:
import sys
import numpy as np
a = np.zeros((5, 5))
print(sys.getrefcount(a)) # 2
a_left_col = a[:, 0]
print(sys.getrefcount(a)) # 3
print(sys.getrefcount(a_left_col.base)) # 3
print(a_left_col.base is a) # True
a = np.ones((5, 5))
print(sys.getrefcount(a_left_col.base)) # 2
请注意a_left_col.base
是对原始数组的引用。当我们重新a
时,对象的引用计数会减少,但它仍然存在,因为它是可以访问的a_left_col
。