Python:如果在try或if中定义,变量仍然可以访问?

时间:2015-07-19 19:37:25

标签: python scope

我是Python初学者,我来自C / C ++背景。我使用的是Python 2.7。

我读过这篇文章:A Beginner’s Guide to Python’s Namespaces, Scope Resolution, and the LEGB Rule,我认为我对Python的这些技术有所了解。

今天我意识到我可以像这样编写Python代码:

if condition_1:
    var_x = some_value
else:
    var_x = another_value
print var_x

也就是说,var_x仍然可以访问,即使定义之前 if。因为我来自C / C ++背景,这对我来说是新的,因为在C / C ++中,var_x在if和else包含的范围内定义,因此除非定义{{{}},否则不能再访问它1}} var_x之前。

我试图在Google上搜索答案,但因为我还不熟悉Python,我甚至不知道从哪里开始以及我应该使用哪些关键字。

我的猜测是,在Python中,if不会创建新范围。 if中新定义的所有变量都在if所在的范围内,这就是if之后仍可访问该变量的原因。但是,如果上面示例中的if仅在var_x中定义,而在if中未定义,则会发出警告,指出else可能引用可能未定义的变量。

我对自己的理解有信心。但是,如果我在某个地方出错,有人可以帮助纠正我,或者给我一个讨论这个问题的文档的链接吗?

感谢。

1 个答案:

答案 0 :(得分:10)

  

我的猜测是,在Python中,if不会创建新范围。 if中新定义的所有变量都在if的范围内,这就是if之后仍然可以访问变量的原因。

这是正确的。在Python中,namespaces基本决定变量作用域,仅为模块和函数(包括方法;基本上任何def)创建。因此,在函数内(而不是在子函数中)发生的所有事情都放在同一名称空间中。

重要的是要知道,在函数中仅仅存在赋值将在本地命名空间中保留一个名称。这会产生一些有趣的情况:

def outer ():
    x = 5
    def inner ():
        print(x)
        # x = 10
    inner()
outer()

在上面的代码中,该行已注释掉,代码将按照您的预期打印5。那是因为inner会在名称x的外部范围内查找。如果您添加了行x = 10,则名称x本地添加到inner,因此之前的会查找{ {1}}将查看x的本地命名空间。但由于尚未分配,您将收到inner“本地变量' x'在分配前引用”)。在Python 3中添加了nonlocal语句来克服以下问题:您希望在内部函数中实际修改外部作用域的UnboundLocalError的情况。

有关名称查找的详细信息,请参阅this related question