[英]Understanding nonlocal in Python 3
I am trying to understand Python 3 variable scoping and nonlocal
. 我试图了解Python 3变量作用域和
nonlocal
。
Consider the following function (it is just an example): 考虑以下功能(仅作为示例):
def build_property(something):
def deco(func):
def getter(self):
return getattr(self, something)
def setter(self, value):
setattr(self, something, value)
return property(getter, setter)
return deco
This works fine without nonlocal
. 没有
nonlocal
这可以正常工作。 But if now I want to conditionally create getters and setters depending on something
I need nonlocal. 但是,如果现在我要有条件地创建依赖于getter和setter
something
,我需要外地。
def build_property(something):
def deco(func):
nonlocal something # This is needed
if something.startswith('A'):
getter = None
else:
def getter(self):
return getattr(self, something)
if something.startswith('B'):
setter = None
else:
def setter(self, value):
setattr(self, something, value)
return property(getter, setter)
return deco
Why is nonlocal
needed in one case, but not in the other? 为什么在一种情况下需要
nonlocal
,而在另一种情况下却不需要? In other word, why something
if correctly found in the first case (without nonlocal
), but in the second I get: "UnboundLocalError: local variable 'something' referenced before assignment" if nonlocal
is not present? 换句话说,为什么
something
如果正确发现首例(不含nonlocal
),但在第二个我得到:“UnboundLocalError:赋值之前引用局部变量‘东西’”,如果nonlocal
是不存在?
First: nonlocal
is not necessary in the code you've written. 首先:在您编写的代码中,
nonlocal
不是必需的。 You're not changing the object that something
points to. 您没有更改
something
对象指向的对象。
Second: There are cases where you would need to use nonlocal
. 第二:在某些情况下,您需要使用
nonlocal
。 Below is some code where nonlocal
is necessary. 以下是一些需要
nonlocal
代码的代码。 Note that all of the assertions are correct (That is, they do not raise an AssertionError). 请注意,所有断言都是正确的(也就是说,它们不会引发AssertionError)。
def main():
variable = 1
def function():
variable = 2
function()
assert variable == 1
def function():
nonlocal variable
variable = 2
function()
assert variable == 2
if __name__ == '__main__':
main()
Third: The code you've presented does not produce the error that you claim it does. 第三:您提供的代码不会产生您声称的错误。 If I remove the
nonlocal
line, and call the following functions, I get no errors. 如果删除
nonlocal
行,并调用以下函数,则不会出错。
build_property('A')(lambda: True)
build_property('B')(lambda: True)
build_property('C')(lambda: True)
def A(d):
outer = object()
d["outer"] = outer
def B():
print locals()
assert d["outer"] is outer #This fails and never reaches
inner = object()
d=dict() #this line.
print locals()
def C():
print locals()
assert d["outer"] is outer #This goes on fine.
inner = object()
print locals()
return B,C
=> b,c = A(dict())
=> c()
-snip, AOK-
=> b()
UnboundLocalError: local variable 'd' referenced before assignment
I'm sorry, I deserve the flame. 对不起,我该当大火。 Above code I wrote up quickly, makes the answer that was previously here a bunch of nonsense.
上面的代码我很快就写了,使以前这里的答案很废话。
But it's surprising. 但这令人惊讶。 I always thought of python(2.x) as a completely foresight-less language, evaluating everything at the last moment...
我一直认为python(2.x)是一种完全没有先见之明的语言,在最后一刻对所有内容进行了评估...
Sorry for what now is off-topic. 抱歉,现在没有主题了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.