我用Python编写代码,试图决定是返回numpy数组(其他数组上diff的结果)还是返回纽比。在哪里(diff)[0],这是一个较小的数组,但需要很少的额外工作来创建。让我们调用发生这种情况的方法methodB。在
我从methodA调用methodB。问题在于,我不一定总是需要methodA中的where()结果,但我可能需要。那么,在methodB中做这项工作值得吗,还是应该将(内存更大的)diff本身传回,然后在methodA中进一步处理它(如果需要的话)?假设methodA只得到结果的引用,这将是更有效的选择。在
那么,当函数结果被传回调用该函数的代码时,它们是否从未被复制过?
我相信当methodB完成时,它框架中的所有内存都将被系统回收,因此methodA必须将methodB返回的任何内容复制到自己的框架中,以便能够使用它。我称之为“价值回报”。这是对的吗?在
是的,你是对的。在Python中,参数总是按值传递,返回值总是按值返回。但是,返回(或传递)的值是对潜在共享、可能可变的对象的引用。在
对于某些类型,返回或传递的值可能是实际对象本身,例如,整数就是这种情况,但这两者之间的区别只能在可变对象中观察到,而整数不是可变对象,而且取消引用对象引用是完全透明的,因此您永远不会注意到这种差异。为了简化你的心智模型,你可以假设参数和返回值总是通过值传递的(无论如何这是真的),并且传递的值总是一个引用(这并不总是正确的,但是你不能分辨区别,你可以把它当作一个简单的性能优化)。在
请注意,通过值传递/返回引用与通过引用传递/返回完全不同(当然不是一回事)。特别是,not允许您在调用者/被调用者中改变名称绑定,因为pass-by-reference允许您这样做。在
这种特殊风格的传递值,其中的值通常是一个引用,在ECMAScript、Ruby、Smalltalk和Java中是相同的,有时被称为“按对象共享调用”(我相信是由Barbara Liskov首创)、“按共享调用”、“按对象调用”,特别是在Python社区中“call by assignment”(感谢@timgeb)或“call by name binding”(感谢@Terry Jan Reedy)(不要与call by name混淆,这又是另一回事)。在
分配从不复制数据。如果您有一个返回值的函数}。在
foo
,那么像result = foo(arg)
这样的赋值永远不会复制任何数据。(当然,可以在函数体中进行复制操作。)同样,return x
不复制对象{你的问题没有一个具体的例子,所以我不能再详细说明了。在
编辑:你应该看看精彩的Facts and Myths about Python names and values演讲。在
你的代码大致如下:
arr
是一个(大)数组,它传递对methodA
和{diff
是在methodB
中生成的类似大小的数组。如果返回,则在methodA
命名空间中由x
引用它。退回时不复印。在如果返回
where
数组,diff
将在methodB
返回时消失。假设它不与其他数组(例如arr
)共享数据缓冲区,那么它占用的所有内存都将恢复。在但是只要内存不紧张,返回
diff
而不是where
结果不会更昂贵。返回期间不复制任何内容。在numpy数组由小的对象包装器组成,这些包装器具有}之间有一个重要的区别。在
shape
和dtype
等属性。它还有一个指向潜在大的data buffer
的指针。在可能的情况下,numpy
尝试共享缓冲区,但很容易生成新的ndarray
对象。因此view
和{相关问题 更多 >
编程相关推荐