【问题标题】:nonlocal for a method inside a class in Python 3.6.0Python 3.6.0 中类内部方法的非本地方法
【发布时间】:2017-02-26 20:13:54
【问题描述】:

我已经搜索过这个,但我找不到任何东西。在Python documentation 9.2.1 中给出了一个示例,使用函数scope_test()

def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)

当我将其更改为 class 并运行它时,我得到:

SyntaxError: no binding for nonlocal 'spam' found

我认为'nonlocal' 不适用于类内的方法,但它仅适用于函数内的函数查找。我在网上找到的所有答案都是针对函数的,而不是针对类的。

  • 为什么 nonlocal 不适用于类?
  • 有什么办法吗?

【问题讨论】:

    标签: python python-3.x


    【解决方案1】:

    nonlocal 当然适用于类中的方法,您只需要将函数嵌套在方法中(我这里使用的是静态方法):

    class Foo:
        @staticmethod
        def scope_test():
            def do_local():
                spam = "local spam"
    
            def do_nonlocal():
                nonlocal spam
                spam = "nonlocal spam"
    
            def do_global():
                global spam
                spam = "global spam"
    
            spam = "test spam"
            do_local()
            print("After local assignment:", spam)
            do_nonlocal()
            print("After nonlocal assignment:", spam)
            do_global()
            print("After global assignment:", spam)
    
    Foo.scope_test()
    print("In global scope:", spam)
    

    使scope_test 成为一个类不会引入nonlocal 工作所需的嵌套。你仍然需要嵌套。

    【讨论】:

      【解决方案2】:

      在该示例中显示的词法范围仅适用于函数命名空间。想象一下,如果这在一个类中工作 - 那么所有类方法都能够直接访问类属性,而不是通过self 参数或类名,因为事情实际上是有效的。

      换句话说,类的命名空间没有为类中的方法引入封闭范围,这也阻止了nonlocal 查找类主体级绑定。

      【讨论】:

        猜你喜欢
        • 2015-06-19
        • 2018-12-07
        • 1970-01-01
        • 2014-04-01
        • 2019-01-05
        • 1970-01-01
        • 1970-01-01
        • 2014-02-07
        • 1970-01-01
        相关资源
        最近更新 更多