【问题标题】:Why does assigning to my global variables not work in Python?为什么分配给我的全局变量在 Python 中不起作用?
【发布时间】:2009-05-30 14:09:18
【问题描述】:

我在尝试理解 python 范围规则时遇到了可怕的麻烦。

使用以下脚本:

a = 7

def printA():
    print "Value of a is %d" % (a)

def setA(value):
    a = value
    print "Inside setA, a is now %d" %(a)


print "Before setA"
printA()
setA(42)
print "After setA"
printA()

给出意想不到的(对我而言)输出:

设置A之前 a 的值为 7 在 setA 中,a 现在是 42 设置A之后 a 的值为 7

我希望最后一次打印 a 的值是 42,而不是 7。关于 Python 的全局变量范围规则,我缺少什么?

【问题讨论】:

    标签: python global-variables scope


    【解决方案1】:

    全局变量是特殊的。如果您尝试在函数内部分配变量a = value,它会在函数内部创建一个新的局部变量,即使存在同名的全局变量也是如此。要改为访问全局变量,请在函数内添加 global statement

    a = 7
    def setA(value):
        global a   # declare a to be a global
        a = value  # this sets the global value of a
    

    有关 Python 命名和绑定规则的详细说明,另请参阅 Naming and binding

    【讨论】:

    • 我想执行类似a = a + value 的操作。它会引发相同的错误。有什么解决方法吗?
    【解决方案2】:

    理解这一点的诀窍是,当您使用 = 为变量赋值时,您还将其声明为局部变量。因此,setA(value) 并没有改变全局变量 a 的值,而是将一个局部变量(恰好称为 a)设置为传入的值。

    如果您尝试像这样在 setA(value) 的开头打印 a 的值,这会变得更加明显:

    def setA(value):
        print "Before assignment, a is %d" % (a)
        a = value
        print "Inside setA, a is now %d" % (a)
    

    如果你尝试运行这个 Python 会给你一个有用的错误:

    回溯(最近一次通话最后): 文件“scopeTest.py”,第 14 行,在 设置A(42) 文件“scopeTest.py”,第 7 行,在 setA 中 print "赋值前,a 为 %d" % (a) UnboundLocalError:分配前引用的局部变量“a”

    这告诉我们 Python 已经决定 setA(value) 函数有一个名为 a 的局部变量,当你在函数中分配给它时,你会改变它。如果你不给函数中的 a 赋值(与 printA() 一样),那么 Python 会使用全局变量 A。

    要将变量标记为全局变量,您需要在 Python 中使用 global 关键字,在要使用全局变量的范围内。在这种情况下,它在 setA(value) 函数中。于是脚本就变成了:

    a = 7
    
    def printA():
        print "Value of a is %d" % (a)
    
    def setA(value):
        global a
        a = value
        print "Inside setA, a is now %d" %(a)
    
    
    print "Before setA"
    printA()
    setA(42)
    print "After setA"
    printA()
    

    这一行添加告诉 Python,当您在 setA(value) 函数中使用变量 a 时,您所说的是全局变量,而不是局部变量。

    【讨论】:

      【解决方案3】:

      函数内部,a被视为局部变量,需要定义

      全局a

      在方法内部使用它之前,在函数内部,即使你已经在方法外部定义了它。

      【讨论】:

        【解决方案4】:

        Python 没有其他语言的变量概念。您有“某处”的对象,并且您有对这些对象的引用。 = 用于将这些对象分配给 current 命名空间中的引用。

        您在 setA 函数的命名空间中创建一个名称 a,该名称引用值所引用的对象。

        【讨论】:

          【解决方案5】:

          函数的执行引入了一个新的符号表,用于函数的局部变量。更准确地说,函数中的所有变量赋值都将值存储在本地符号表中;而变量引用首先在局部符号表中查找,然后在封闭函数的局部符号表中查找,然后在全局符号表中查找,最后在内置名称表中查找。因此,全局变量不能在函数内直接赋值(除非在全局语句中命名),尽管它们可以被引用。

          【讨论】:

            猜你喜欢
            • 2021-01-22
            • 1970-01-01
            • 1970-01-01
            • 2019-09-27
            • 2021-01-12
            • 1970-01-01
            • 1970-01-01
            • 2016-12-30
            • 2015-06-25
            相关资源
            最近更新 更多