我正在尝试理解下面代码的callstack,我无法回答它。
为什么这一行返回4:
7. return z
为什么这一行5:
16 x = x + m1(x)
希望你能帮助我。
1 def m1(x):
2 x = x + 1
3 z = m2(x, 4)
4 x = x + 1
5 z = z + 1
6 print(x)
7 return z
8
9 def m2(x, y):
10 x = x + 1
11 y = y + 1
12 print(x, y)
13 return x
14
15 x = 1
16 x = x + m1(x)
答案 0 :(得分:1)
这是因为变量x和z是不可变的。
在python中,当我们将不可变参数传递给函数时,通过引用调用不再适用。
一旦我们改变这种变量的值,函数就会创建自己的副本,即局部变量。这就是背后的原因。
Please refer this for more information
答案 1 :(得分:1)
我怀疑你需要知道的是函数内部的变量与函数外部的变量不同。或者更准确地说,每次调用一个函数时,都会为该函数调用创建一组新的变量,与其他可能碰巧具有相同名称的变量无关。 (极少数例外。)因此,例如,如果你写了
def f1(x):
x = x + 1
return x
x = 1
x = f1(x)
x = f1(x)
print(x)
实际上有三个名为x
的独立变量:顶级的变量(“global”),初始化为1,为第一次调用f1
而创建的变量,为第二次调用[{1}}创建的那个。如果你注释他们的名字以便彼此区分,那么实际上会发生什么:
f1
通过这个,您可以看到不同变量如何分开,即使它们在代码中具有相同的名称。每个变量都有自己的“区域”,其中名称是指该变量,而在不同的“区域”中,相同的名称是指不同的变量。这称为scoping。
我提到有一些例外。这是两个有点常见的:
当您希望该名称在函数内部引用与函数外部相同的内容时,Python允许您在函数内部放置“全局声明”。所以,如果我像这样定义x_global = 1
# Python does this behind the scenes
f1_call1_argument1 = x_global
# call f1
x_f1_call1 = f1_call1_argument1
# now your code in f1 starts running
x_f1_call1 = x_f1_call1 + 1
f1_call1_return_value = x_f1_call1
# return from f1
x_global = f1_call1_return_value
# now repeat but with the second call to f1
f1_call2_argument1 = x_global
x_f1_call2 = f1_call2_argument1
x_f1_call2 = x_f1_call2 + 1
f1_call2_return_value = x_f1_call2
x_global = f1_call2_return_value
print(x_global)
:
f2
然后就没有def f2():
global x
x = x + 1
return x
的功能特定(“本地”)版本。它只会使用全局x
。运行此代码
x
会像这样工作:
x = 1
x = f2()
x = f2()
您还可以拥有参数的默认值,并且由于Python实现方式的设计决策,默认值有效地存储在函数调用之间存在的不可见变量中。如果我有
x_global = 1
# call f2
x_global = x_global + 1
f2_call1_return_value = x_global
# return from f2
x_global = f2_call1_return_value
x_global = x_global + 1
f2_call2_return_value = x_f1_call2
x_global = f2_call2_return_value
(我正在使用列表,因为它可以更改,但是整数不能更改)然后它的工作原理如下:
def f3(x=[]):
x.append(5)
return x
x = [1]
x = f3()
x = f3()