python试图理解callstacks

时间:2018-01-21 09:39:51

标签: python callstack

我正在尝试理解下面代码的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)

2 个答案:

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