2012-07-20 72 views
35

我碰到一个事实,即numpy阵列通过引用在多个地方通过,但后来当我执行下面的代码,为什么会出现我使用的foo行为和barnumpy数组是否通过引用传递?

import numpy as np 

def foo(arr): 
    arr = arr - 3 

def bar(arr): 
    arr -= 3 

a = np.array([3, 4, 5]) 
foo(a) 
print a # prints [3, 4, 5] 

bar(a) 
print a # prints [0, 1, 2] 

之间的差异来python 2.7和numpy版本1.6.1

+1

相关:http://stackoverflow.com/q/9047111/166749 – 2012-07-20 19:58:45

+0

这个东西Python调用“引用”与传递引用无关,这就是为什么。 – delnan 2012-07-20 20:06:06

回答

46

在Python中,all variable names are references to values

Python在评估任务时,the right-hand side is evaluated before the left-hand sidearr - 3创建一个新的数组;它不会在原地修改arr

arr = arr - 3使得本地变量arr引用这个新数组。它不会修改arr最初引用的值,该值已传递到foo。变量名称arr只是绑定到新阵列,arr - 3。此外,arrfoo函数范围内的局部变量名称。一旦foo函数完成,没有更多的参考arr和Python可以自由垃圾收集它引用的值。 As Reti43 points out,为了arr的价值影响afoo必须返回arra必须分配给该值:

def foo(arr): 
    arr = arr - 3 
    return arr 
    # or simply combine both lines into `return arr - 3` 

a = foo(a) 

相比之下,arr -= 3,其中Python的转化为对__iadd__ special method一个电话,并修改该阵列在原地由arr引用。

+6

这是一种,不直观的... – Mehdi 2015-12-14 14:19:08

+0

因此,为了'foo()'有效果,它需要返回'arr',并在代码中运行它为'a = foo(a) 。 – Reti43 2015-12-14 17:46:32

+0

等等,对象是通过引用python中的函数传递的......? – 2017-07-11 01:09:11

8

第一个函数计算(arr - 3),然后分配本地名称arr到它,这不会影响通过阵列的数据。我的猜测是,在第二个功能,np.array覆盖-=运营商,并在地方上工作阵列数据。