python - 为什么 Python 不能在闭包中增加变量?

标签 python closures

在这个代码片段中,我可以从 bar 函数内部打印 counter 的值

def foo():
    counter = 1
    def bar():
        print("bar", counter)
    return bar

bar = foo()

bar()

但是当我尝试从 bar 函数内部增加计数器时,我得到一个 UnboundLocalError 错误。

UnboundLocalError: local variable 'counter' referenced before assignment

带有增量语句的代码片段。

def foo():
    counter = 1
    def bar():
        counter += 1
        print("bar", counter)
    return bar

bar = foo()

bar()

您是否仅对 Python 闭包中的外部函数中的变量具有读取权限?

最佳答案

您不能在 Python 2 中重新绑定(bind)闭包变量。在 Python 3 中,由于您的 print(),您似乎正在使用它,您可以将它们声明为 nonlocal:

def foo():

  counter = 1

  def bar():
    nonlocal counter
    counter += 1
    print("bar", counter)

  return bar

bar = foo()
bar()

否则,bar() 中的赋值会使变量成为局部变量,并且由于您没有在局部范围内为变量赋值,因此尝试访问它是错误的。

在 Python 2 中,我最喜欢的解决方法如下所示:

def foo():

  class nonlocal:
    counter = 1

  def bar():
    nonlocal.counter += 1
    print("bar", nonlocal.counter)

  return bar

bar = foo()
bar()

这是可行的,因为改变可变对象不需要更改变量名称指向的内容。在这种情况下,nonlocal 是闭包变量,它永远不会被重新分配;仅更改其内容。其他解决方法使用列表或字典。

或者你可以为整个事情使用一个类,正如@naomik 在评论中建议的那样。定义 __call__() 以使实例可调用。

class Foo(object):

    def __init__(self, counter=1):
       self.counter = counter

    def __call__(self):
       self.counter += 1
       print("bar", self.counter)

bar = Foo()
bar()

关于python - 为什么 Python 不能在闭包中增加变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21959985/

相关文章:

python - 如何在 jupyter notebook 中将 tqdm 与 pandas 一起使用?

python - 将数据从 sqlite 导出到 numpy 数组

python - 使用 map 功能

generics - 是否可以在具有通用参数和返回类型的结构中使用闭包?

python - 在python中向预先存在的字典键添加一个值

python - 在 Python 中创建一个 IF 语句来查看之前的 IF 语句输出

function - "Side-effecting lexical closure"vs Scala 中的函数

javascript - 命名函数和匿名函数有不同的效果

javascript - 有没有办法将索引值保留在 javascript 中的函数本地

javascript - 无法理解 Javascript 闭包示例