简体   繁体   English

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

[英]How does Python handle inner functions with nonlocal effects on their parameters?

Consider the following function, which we'd like to not be constant on integers a , but which always returns (1,2) : 考虑以下函数,我们希望在整数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)

If I understand correctly, the idiomatic way to implement bar(b,c) would be to give it no parameters at all and declare b and c nonlocal inside its definition. 如果我理解正确,实现bar(b,c)的惯用方法是根本不给它任何参数,并在其定义中声明b和c非局部。 I'm curious, however: how do we make an inner function have nonlocal effects on its parameters? 然而,我很好奇:我们如何使内部函数对其参数产生非局部效应?

As stated in this answer for Python 2.x: 正如Python 2.x的回答中所述:

Python doesn't allow you to reassign the value of a variable from an outer scope in an inner scope (unless you're using the keyword "global", which doesn't apply in this case). Python不允许您从内部作用域中的外部作用域重新分配变量的值(除非您使用关键字“global”,在这种情况下不适用)。

This will return (2,3) : 这将返回(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))

Make b and c function attributes. 制作bc 函数属性。

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)

Notice you no longer pass b or c into the function bar. 请注意,您不再将b或c传递到功能栏中。

Function parameters are always locals. 函数参数始终是本地的。 You could pass in mutable objects however, and apply your operations to the indirectly referenced value: 但是,您可以传入可变对象,并将操作应用于间接引用的值:

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])

The changes you make to the mutable object are shared with any other references to those objects, including locals in foo() . 您对可变对象所做的更改将与对这些对象的任何其他引用共享,包括foo()本地对象。

However, if you want something to be a closure, just make it a closure. 但是,如果你想要一个闭包,那就把它变成一个闭包。 There are no use cases for this that cannot be handled by nonlocal values and return . 没有用于nonlocal值和return

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM