【问题标题】:global variable reassignment in pythonpython中的全局变量重新分配
【发布时间】:2019-03-31 02:48:15
【问题描述】:

当我尝试在函数内重新分配变量时,我收到UnboundLocalError 错误。以下是我的问题的 sn-p。

global_variable = 'a'

def abc():
    print(global_variable)
    global_variable = 'b'

abc()

当我执行它时,我得到以下信息:

Traceback (most recent call last):
  File "/Users/arghyasaha/hobby_project/python_experiment/python_experiment/random_experiment/del_me.py", line 7, in <module>
    abc()
  File "/Users/arghyasaha/hobby_project/python_experiment/python_experiment/random_experiment/del_me.py", line 4, in abc
    print(global_variable)
UnboundLocalError: local variable 'global_variable' referenced before assignment

为了解决这个问题,我们可以像这样使用global关键字

global_variable = 'a'

def abc():
    global global_variable
    print(global_variable)
    global_variable = 'b'

abc()

我正在寻找解释,对于这种行为,它似乎有点类似于 javascript 中的提升概念。我确实找到了一些资源,例如source1source2,但它们都没有解释得足够好。有人可以正确解释 python 中到底发生了什么吗?

【问题讨论】:

  • 虽然人们倾向于将 CPython 称为解释型语言,但它是字节码编译的:函数在编译时初始化其命名空间。因此,局部变量 global_variable 在您调用 print(global_variable) 之前就已经在命名空间中,尽管它当时是未绑定的(即没有为其分配引用),因此会出现错误。
  • 这能回答你的问题吗? Python variable scope error

标签: python python-2.7 hoisting


【解决方案1】:

这是因为 Python 编译器在确定哪些变量是该代码块的本地变量时会查看代码块中的所有左值。由于在您的代码中,global_variableabc 的功能块中用作左值,因此在编译时它被视为abc 代码块的局部变量,因此,它被认为是当您尝试 print(global_variable) 在同一块中分配 global_variable 值之前,在为 abc 中分配值之前被引用。

【讨论】:

    【解决方案2】:

    一个变量不能在函数内部既是局部的又是全局的。因此 Python 决定我们需要一个局部变量,因为在 abc() 内部对 global_variable 进行了赋值,所以 global_variable 定义之前的第一个 print 语句会抛出上面的错误消息。如果未将其声明为全局变量,则在函数内部更改或创建的任何变量都是局部变量。为了告诉 Python,我们要使用全局变量,我们必须使用关键字“global”明确说明这一点

    您可以参考https://www.python-course.eu/python3_global_vs_local_variables.php了解更多信息。

    【讨论】:

      【解决方案3】:

      问题在于,当您运行代码并进入函数时, this 有一个 作用域,其中 global_variable 尚未定义。

      【讨论】:

        【解决方案4】:

        注意,如果你写了

        def cba():
            global_variable = 'b'
            print(global_variable)
        
        cba()
        

        不会有例外。这是因为,尽管它的名称,global_variable 将是函数范围内的局部变量。您在函数中分配给的任何变量都是局部变量,除非您另有明确说明。

        在函数中,当你访问一个变量(以某种方式使用它的值,比如在这些示例中打印它)时,python 将首先在本地范围内查找变量,然后在全局范围内查找。

        def xyz():
            print(global_variable)
        

        例如,将访问全局变量。

        当 python 尝试编译您的函数时,它看到 global_variable 被分配给,因此尝试将其视为本地,但随后它尝试在它被定义在该范围内之前访问它。

        global 关键字告诉 python 将该名称视为对该函数的全局范围内的引用,因此赋值会更改全局变量,并且不会在局部范围内引入新变量。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-12
          • 1970-01-01
          • 2018-10-31
          • 1970-01-01
          • 2013-07-06
          • 1970-01-01
          相关资源
          最近更新 更多