由于Python没有指针,我想知道如何将对象的引用传递给函数而不是复制整个对象。这是一个非常人为的例子,但我说我正在写一个这样的函数:
def some_function(x):
c = x/2 + 47
return c
y = 4
z = 12
print some_function(y)
print some_function(z)
根据我的理解,当我调用some_function(y)时,Python会分配新的空间来存储参数值,然后在函数返回c并且不再需要它时删除这些数据。由于我实际上并没有改变some_function中的参数,我怎样才能简单地从函数中引用y而不是在我传递时复制y?在这种情况下,它并不重要,但如果y非常大(比如一个巨大的矩阵),复制它可能会占用一些重要的时间和空间。
答案 0 :(得分:7)
不幸的是,你的理解是完全错误的。 Python 不复制值,也不为新的值分配空间。它传递一个值,该值本身就是对象的引用。如果您修改该对象(而不是重新绑定其名称),则将修改原始对象。
修改强>
我希望你不要担心内存分配:Python不是C ++,几乎所有的时候你都不需要考虑内存。
通过使用类似列表的东西来演示重新绑定更容易:
def my_func(foo):
foo.append(3) # now the source list also has the number 3
foo = [3] # we've re-bound 'foo' to something else, severing the relationship
foo.append(4) # the source list is unaffected
return foo
original = [1, 2]
new = my_func(original)
print original # [1, 2, 3]
print new # [3, 4]
如果您考虑名称而不是变量,这可能有所帮助:在函数内部,名称“foo”开始是对原始列表的引用,但随后我们将该名称更改为指向新的不同列表
答案 1 :(得分:1)
Python参数总是"引用"。
Python中的参数工作方式以及它们在文档中的解释方式可能会让新手对语言产生混淆和误导,特别是如果您有其他语言的背景,可以让您选择"传递值"并且"通过引用传递"。
用Python术语来说,"引用"只是一个带有更多元数据的指针,以帮助垃圾收集器完成其工作。每个变量和每个参数总是"引用"。
所以,在内部,Python传递一个"指针"每个参数。您可以在此示例中轻松看到此内容:
>>> def f(L):
... L.append(3)
...
>>> X = []
>>> f(X)
>>> X
[3]
变量X指向列表,参数L是"指针"的副本。列表,而不是列表本身的副本。
请注意,这与"传递参考"不同。作为带有&
限定符的C ++,或带有var
限定符的pascal。