【问题标题】:why python can't access global variable value with function parameter name change?为什么python无法通过函数参数名称更改访问全局变量值?
【发布时间】:2020-11-27 15:53:24
【问题描述】:

在这两段代码中,为什么第二段给出局部变量赋值错误?两个代码相似,只是函数参数不同,第二个可以读取全局变量,为什么第一个不能读取符号表的参数名称变化?

第一个:

def a(z):
    z+=1
z=3
a(z)

第二个:

def a(z):
    b += 1
b = 5
a(b)

【问题讨论】:

  • 在第一个中,您只更新作为函数参数的局部变量z。在第二个中没有这样的局部变量,所以你得到一个错误。他们都没有更新全局变量。
  • 在第一个中,z+=1 递增传递给函数的 z 参数。模块级 z 变量不相关。在第二个中,您试图增加 b 变量,但是 b 变量尚未在函数中声明并且没有值。因此你会得到一个错误。
  • 您需要了解变量/引用、范围和声明/定义等几个概念。

标签: python scope frame symbol-table


【解决方案1】:

这里没有使用任何全局变量。

在第一个示例中,z 是函数的参数,而不是全局参数。请注意,当您增加z 时,它不会在调用范围内发生变化,因为函数内部的z 是您从函数外部传入的z 的副本。

在第二个例子中,函数内部没有b(参数为z),这就是为什么你在尝试修改函数时会在函数内部出错。

要执行您想要执行的操作,您应该将参数设为一个可变对象,其中包含您尝试更改的值;这样您就可以修改函数内部的值,并且调用者将可以访问新值。您可以为此目的定义一个类,或者您可以简单地将其设为单元素列表:

def a(z):
    z[0] += 1
b = [5]
a(b)  # b == [6]

或者,如果可能,更好的方法是 IMO 不依赖于可变性,而只返回新值,要求调用者在其范围内显式地重新分配它:

def a(z)
    return z + 1
b = 5
b = a(b)  # b == 6

【讨论】:

  • 是的,谢谢,我只是想知道为什么在第一个 sn-p 中 z inside 函数能够获取全局范围的副本,但在第二个代码中却不能这样做函数,其中 b 无法获取全局范围的 b 变量的副本,正如您所提到的,它不是在那里出现问题的函数的参数,如果我错了,请纠正我。谢谢
  • 重要的是,在第一个 sn-p 中,函数内的z 不是来自全局范围
【解决方案2】:

您应该将 def 块视为独立块。

在第一个sn-p中:

def a(z):
    z+=1

z 是什么?是a的第一个参数

在第二个sn-p中:

def a(z):
    b += 1

b 是什么?这是未知的。这就是这段代码失败的原因。

你还应该注意到,在你的第一个sn-p中,z里面的函数和z=3是不一样的:

>>> def a(z):
...     z+=1
...
>>> z=3
>>> a(z)
>>>
>>> z
3

【讨论】:

  • 是的,我只是在想为什么函数内部的参数无法访问全局变量值,这就是为什么我没有得到关于符号表设计方式或解释器编写方式的逻辑,这取决于函数内部的参数与全局参数同名到第一个 sn-p 是否有效或访问全局范围变量的值
【解决方案3】:

在第二个代码中,参数是“z”,您尝试使用“b”访问该参数

def a(z):
    b += 1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多