如何在Python中确定作用域

2022-02-26 00:00:00 python scope global-variables

问题描述

为什么第二个函数中的第一个print语句引发x未定义的错误?

x = 5

def function_a():
    print(x)


def function_b():
    print(x)
    x = 7
    print(x)

运行第一个函数将产生以下结果。

>>> function_a()
5

运行第二个函数时引发错误。

UnboundLocalError: local variable 'x' referenced before assignment

解决方案

Python将推断并在看到内部作用域中声明的变量时使用该变量,即使该变量是在使用之后声明的。

为了演示这一点,我创建了两个方案。


在内部范围内声明的变量

变量按以下顺序推断:局部、非局部和全局。由于x是在内部作用域内声明的,因此Python将推断并使用此作用域中的x,即使它是在使用之后声明的。

请注意,Python无法区分修改和声明;从全局作用域修改x被解释为声明该作用域内的另一个变量x

内部作用域内未声明任何变量

如果在内部作用域中没有声明变量,则Python会将推断的作用域切换到非本地,然后切换到全局。

显式切换作用域

如果您事先显式声明了x的作用域,则Python将不必推断。

下面的代码不会引发错误,因为它使用的作用域显式是全局作用域,而不是内部作用域。

x = 5

def scope():
    global x
    print(x)
    x = 7
    print(x)

作用域

通过选择要使用的作用域,您不仅可以使用该特定作用域中的变量,还可以修改变量。因此,在处理作用域时需要格外小心。

因为Python无法区分变量声明和变量修改,所以我的建议是,如果您要使用全局变量,应该事先显式声明它。

这也适用于嵌套作用域。

x = 5

def outer():
    x = 7

    def inner():
        nonlocal x
        print(x)
        x = 3
        print(x)
    
    inner()

运行外部函数将产生以下结果。

>>> outer()
7
3

尝试将nonlocal关键字更改为global并查看不同的结果;或者完全删除该行以显示错误。

相关文章