采取以下代码
#module functions.py
def foo(input, new_val):
input = new_val
#module main.py
input = 5
functions.foo(input, 10)
print input
我认为输入现在是10.为什么不是这样?
答案 0 :(得分:13)
所有内容都按值传递,但该值是对原始对象的引用。如果修改对象,则调用者可以看到更改,但无法重新分配名称。此外,许多对象是不可变的(整数,浮点数,字符串,元组)。
答案 1 :(得分:8)
在foo中,您将本地名称input
绑定到另一个对象(10
)。在调用上下文中,名称input
仍然引用5
对象。
答案 2 :(得分:5)
Python中的赋值不会就地修改对象。它重新绑定一个名称,以便在input = new_val
之后,局部变量input
获得一个新值。
如果要修改“outside”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;
}
答案 3 :(得分:3)
Python既不是按值调用,也不是按引用调用,而是Call By Object。
“参数通过call-by-sharing,类似传递给 按值调用,除了参数是对象 并且只有在它们可变的情况下才能改变。“
答案 4 :(得分:0)
好吧,python函数既不是按引用调用也不是按值调用,它们不是按对象调用。 在将此概念应用于函数之前,让我们看一下这些代码片段:
1-
listA = [0]
listB = listA
listB.append(1)
print (listA) # [0, 1]
2-
listA = [0]
listB = listA
listB = [2, 3]
print(listA) # [0]
在第一个代码段中,listB能够访问存储在listA中的对象并对其进行修改,但不能在第二个代码段中对其进行修改,因为它们不是同一件事!您传递了一个对象容器,并且能够修改该容器中的对象,但是您不能修改该容器本身。 在您的代码中:
def foo(input, new_val):
input = new_val
input = 5
foo(input, 10)
print (input)
您无法修改变量“输入”,因为您没有它! 通过对象传递是一个非常令人困惑的概念,让我想起了量子物理学,但是,尝试尝试一下代码,您会很好地理解它。 您可以查看以下链接以获取更多插图: