理解 Python 3 中的非本地

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不存在?

Bil*_*nch 5

首先: 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)