我是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
可能引用可能未定义的变量。
我对自己的理解有信心。但是,如果我在某个地方出错,有人可以帮助纠正我,或者给我一个讨论这个问题的文档的链接吗?
感谢。
答案 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。