python中的作用域规则

时间:2018-05-10 10:59:09

标签: python python-3.x

考虑以下python片段(我正在运行Python 3)

name = "Sammy" 

def greet():
    name = 'johny'
    def hello():
        print('hello ' + name) # gets 'name' from the enclosing 'greet'
    hello()

greet()

这会产生预期的输出hello johny

然而,

x = 50

def func1():
    x = 20
    def func2():
        print("x is ", x) # Generates error here
        x = 2
        print("Changed the local x to ",x)
    func2()

func1()
print("x is still ",x)

生成UnboundLocalError: local variable 'x' referenced before assignment

为什么第一个代码段有效,而第二个则没有?

1 个答案:

答案 0 :(得分:4)

错误实际上是由以下行(间接)引起的,即x = 2。尝试注释掉该行,您将看到该功能正常工作。

对于名为x的变量赋值的事实使x编译时的函数本地化,但是,执行时x的第一次引用失败,因为在执行print()语句时,它在当前范围中尚不存在

使用func2()中的nonlocal更正

def func2():
    nonlocal x
    print("x is ", x)
    x = 2
    print("Changed the local x to ",x)

第一个函数(greet())工作的原因是因为可以读取外部作用域中的变量,但是,除非指定变量存在于外部作用域中,否则不能分配它们(使用nonlocalglobal)。

但是,您可以指定一个同名的变量,它将创建一个新的局部变量,而不是外部作用域中的变量。所以这也有效:

def func1():
    x = 20
    def func2():
        x = 2
        print('Inner x is', x)
    func2()
    print('Outer x is', x)

此处x在被引用之前被分配。这会在函数x的范围内创建一个名为func2()的新变量,该变量会隐藏x中定义的func1()