Her*_*nan 2 python scoping python-3.x python-nonlocal
我试图理解 Python 3 变量范围和nonlocal.
考虑以下函数(这只是一个示例):
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
Run Code Online (Sandbox Code Playgroud)
这在没有nonlocal. 但如果现在我想根据something我需要的非本地条件有条件地创建 getter 和 setter。
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
Run Code Online (Sandbox Code Playgroud)
为什么nonlocal在一种情况下需要,但在另一种情况下不需要?换句话说,为什么something如果在第一种情况下正确找到(没有nonlocal),但在第二种情况下我得到:“UnboundLocalError:赋值之前引用的局部变量'某物'”如果nonlocal不存在?
首先: nonlocal在您编写的代码中不是必需的。something您没有更改指向的对象。
第二:在某些情况下您需要使用nonlocal. 下面是一些必要的代码nonlocal。请注意,所有断言都是正确的(也就是说,它们不会引发 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()
Run Code Online (Sandbox Code Playgroud)
第三:您提供的代码不会产生您声称的错误。如果我删除该nonlocal行并调用以下函数,则不会出现错误。
build_property('A')(lambda: True)
build_property('B')(lambda: True)
build_property('C')(lambda: True)
Run Code Online (Sandbox Code Playgroud)