我以为Python通过引用传递了所有东西?

时间:2011-11-18 14:47:51

标签: python scope

采取以下代码

#module functions.py
def foo(input, new_val):
    input = new_val

#module main.py
input = 5
functions.foo(input, 10)

print input

我认为输入现在是10.为什么不是这样?

5 个答案:

答案 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)

您无法修改变量“输入”,因为您没有它! 通过对象传递是一个非常令人困惑的概念,让我想起了量子物理学,但是,尝试尝试一下代码,您会很好地理解它。 您可以查看以下链接以获取更多插图:

geeks for geeks

ROBERT HEATON blog