看看下面的代码我以为Python通过引用传递了一切吗?
#module functions.py
def foo(input, new_val):
input = new_val
#module main.py
input = 5
functions.foo(input, 10)
print input
我想输入现在是10.这是为什么不是这样?
看看下面的代码我以为Python通过引用传递了一切吗?
#module functions.py
def foo(input, new_val):
input = new_val
#module main.py
input = 5
functions.foo(input, 10)
print input
我想输入现在是10.这是为什么不是这样?
一切都按值传递,但该值是对原始对象的引用。如果修改对象,则更改对于调用者可见,但不能重新分配名称。而且,许多对象是不可变的(整数,浮点数,字符串,元组)。
“[习惯Python](http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#other-languages-have-variables)”很好地说明了这种现象。 –
Python不是按值或按引用调用,请参阅我的答案了解详细信息。 –
@skyhisi:除了使用非标准术语“按对象调用”之外,您的答案与我的答案基本相同,我故意避免使用非标准术语,因为它没有解释任何事情。 –
在foo中,您将当地名称input
绑定到不同的对象(10
)。在调用上下文中,名称input
仍指5
对象。
Python中的赋值不会就地修改对象。它重新命名一个名称,以便在input = new_val
之后,本地变量input
获得新值。
如果要修改“外” input
,你必须把它包一个可变的对象内,如一个元素的列表:
def foo(input, new_val):
input[0] = new_val
foo([input])
Python不通过就按引用就像C++引用传递的工作方式一样。在这种情况下,至少,它更仿佛每个参数是在C/C++的指针:
// effectively a no-op!
void foo(object *input, object *new_val)
{
input = new_val;
}
感谢大家的回答......你提出的这个方法看起来几乎就像一个黑客,这是标准程序吗?有没有其他方法可以修改更pythonic的不可变类型? (我想'修改不可变类型'回答我自己的问题,但我会问无论如何...) – Ferguzz
@Ferguzz你不能通过定义修改不可变对象。但那真的是你要问的吗?到目前为止,甚至还没有提到不可变对象。 “var = ...”不修改任何对象或任何其他变量的事实与不变性无关。你不能让一个变量赋值改变另一个变量,就像你不能改变一个列表会影响另一个列表一样。 – delnan
我指的是这个答案中的一行'将它包装在一个可变对象(如列表)中“。我试图问,有没有办法像我原来的帖子那样修改变量,而不这样做? – Ferguzz
Python是既不呼叫按值,或呼叫按引用,它是Call By Object。
“参数被调用的共享传递,类似到 呼叫按值,除了自变量的对象 ,如果他们是可变的,只能改变。”
不错的总结,但我仍然认为逐个对象与按值调用没有区别,所有“值”都是对象的句柄(〜=指针)。 – Kos
通过在函数foo的定义中调用局部变量“input”,您可能会迷惑自己。另外,斯文在答案中说。 – phkahler
无论你在哪里阅读过,Python都会通过引用传递所有内容,它们是错误的。 –