【发布时间】:2022-01-23 05:38:43
【问题描述】:
考虑以下数组操作:
import numpy as np
def f(x):
x += 1
x = np.zeros(1)
f(x) # changes `x`
f(x[0]) # doesn't change `x`
x[0] += 1 # changes `x`
为什么x[0] 的行为会根据+= 1 发生在函数f 内部还是外部而有所不同?
我可以将数组的一部分传递给函数,以便函数修改原始数组吗?
编辑:如果我们考虑= 而不是+=,我们可能会保持问题的核心,同时消除一些不相关的复杂性。
【问题讨论】:
-
因为你传递 x[0] ,你只是传递那个值(作为一个对象)而不是整个 x 对象
-
@eshirvana 如果passing复制,为什么
f(x)修改x?如果 indexing 进行复制,为什么x[0] += 1会修改原件?如果passing只有在有indexing的情况下才会做一个copy,那么passing怎么知道有没有indexing,为什么要实现这个依赖呢? -
x是可变的,x[0]不是。这意味着__iadd__可以修改x 但不能修改x[0]。这实际上与索引无关。如果x[0]是可变的并且定义了__iadd__方法来修改它,那也会改变。用二维数组试试,你会看到传递x[0]会改变它的第一行。 -
是的,
__iadd__是+=。当您执行x[0] = 1或x[0] = x[0] + 1或x[0] += 1并且x[0] 是一个整数时,您并没有真正修改那里的整数,而是将其指向不同的整数。 Ned Batchelder 对此有很好的article。 -
@root 是的,就是这样。
__getitem__返回一个新对象,__setitem__改变底层缓冲区...您必须了解这些基本上只是调用方法的糖。原则上,它们可以做任何事情,而且它们不必彼此保持一致
标签: python numpy scope pass-by-reference numpy-ndarray