Python 通过引用传递数组:
$:python
...python startup message
>>> import numpy as np
>>> x = np.zeros((2,2))
>>> x
array([[0.,0.],[0.,0.]])
>>> def setx(x):
... x[0,0] = 1
...
>>> setx(x)
>>> x
array([[1.,0.],[0.,0.]])
最佳答案是指即使在已编译的 c 代码中也会发生的现象,因为任何 BLAS 事件都将涉及“读取”步骤,在该步骤中,用户(在这种情况下为代码编写者)知道形成一个新数组,或者在用户不知道的临时变量中“在后台”形成一个新数组(您可能会将其视为.eval()
调用)。
但是,我可以清楚地访问数组的内存,就好像它在比调用的函数(即,setx(...)
)更全局的范围内;就编写代码而言,这正是“通过引用传递”的含义。
让我们再做一些测试来检查接受答案的有效性:
(continuing the session above)
>>> def minus2(x):
... x[:,:] -= 2
...
>>> minus2(x)
>>> x
array([[-1.,-2.],[-2.,-2.]])
似乎是通过引用传递的。让我们做一个计算,它肯定会在底层计算一个中间数组,看看 x 是否像通过引用传递一样被修改:
>>> def pow2(x):
... x = x * x
...
>>> pow2(x)
>>> x
array([[-1.,-2.],[-2.,-2.]])
嗯,我以为 x 是通过引用传递的,但也许不是?-- 不,在这里,我们用一个全新的声明(通过 python 中的解释隐藏)隐藏了 x,并且 python 不会将这种“阴影”传播回全局范围(这将违反 python 用例:即,成为初学者仍然可以被专家有效使用的编码语言)。
但是,我可以通过强制修改内存(当我将 x 提交给函数时不会复制)来以“按引用传递”的方式非常轻松地执行此操作:
>>> def refpow2(x):
... x *= x
...
>>> refpow2(x)
>>> x
array([[1., 4.],[4., 4.]])
所以你看到python可以做一些你想做的事情。