Python如何使用非局部效应处理内部函数?

时间:2016-02-11 21:33:08

标签: python scoping

考虑以下函数,我们希望它不能在整数a上保持不变,但总是返回(1,2)

def foo(a):
    b = 1
    c = 2
    def bar(b,c):
        b = b + a
        c = c + a
    bar(b,c)
    return (b,c)

如果我理解正确,那么实现bar(b,c)的惯用方法就是不给它任何参数,并在其定义中声明b和c非局部。然而,我很好奇:我们如何使内部函数对其参数产生非局部效应?

3 个答案:

答案 0 :(得分:3)

正如this answer中针对Python 2.x所述:

  

Python不允许您从中重新分配变量的值   内部范围中的外部范围(除非您使用关键字   “全球”,在这种情况下不适用。)

这将返回(2,3)

def foo(a):
    b = 1
    c = 2
    def bar(b,c):
        b = b + a
        c = c + a
        return b, c
    b, c = bar(b,c)
    return (b,c)

print(foo(1))

答案 1 :(得分:2)

制作bc function attributes.

def foo(a):
    foo.b = 1
    foo.c = 2
    def bar():
        foo.b = foo.b + a
        foo.c = foo.c + a
    bar()
    return (foo.b,foo.c)

请注意,您不再将b或c传递到功能栏中。

答案 2 :(得分:2)

功能参数始终本地。但是,您可以传入可变对象,并将操作应用于间接引用的值:

def foo(a):
    b = [1]
    c = [2]
    def bar(b, c):
        b[0] += a
        c[0] += a
    bar(b, c)
    return (b[0], c[0])

您对可变对象所做的更改将与对这些对象的任何其他引用共享,包括foo()中的本地对象。

但是,如果你想要一个闭包,那就把它当成一个闭包。 nonlocal值和return无法处理此用例。