当前位置: 首页 > 面试题库 >

为什么Python无法在闭包中增加变量?

商同化
2023-03-14
问题内容

在此代码段中,我可以从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中对闭包变量进行突变。在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()


 类似资料:
  • 你能帮我理解一下为什么我不能增加静态变量吗?我面临以下问题:*错误LNK2001:未解析的外部符号“private:static unsigned int counter::m_curcounters”(?m_curcounters@counter@@0ia)*

  • 问题内容: 在Python中的类上定义方法时,它看起来像这样: 但是在某些其他语言(例如C#)中,你可以使用“ this”关键字来引用该方法所绑定的对象,而无需在方法原型中将其声明为参数。 这是Python中的一种故意的语言设计决策,还是有一些实现细节需要传递“ self”作为参数? 问题答案: 我喜欢引用Peters的。“显式比隐式好。” 在Java和.可以推断出’ ‘,除非你拥有无法推断的变量

  • 问题内容: 我正在阅读,发现在关闭正文之后,自己对“()”并不真正了解: 在: func(ch chan int){ch < -ACK } (replyChan) ` 在的示例中: 我不清楚关闭主体后添加和使用“()”的原因,希望有人可以清楚地解释一下。 问题答案: 这并不是说必须(仅)一个后添加 封 在。defer语句的语言规范要求其“ Expression” 始终 必须是函数调用。 为什么会这

  • 问题内容: 我已经在Python中看到并使用了嵌套函数,它们与闭包的定义匹配。那么为什么叫他们而不是? 嵌套函数不是因为外部世界不使用闭包吗? 更新:我正在阅读有关闭包的知识,这让我开始思考关于Python的这个概念。我搜索并找到某人在下面的评论中提到的文章,但是我无法完全理解该文章中的解释,所以这就是为什么我问这个问题。 问题答案: 当函数可以从完成其执行的封闭范围访问局部变量时,就会发生关闭。

  • 问题内容: 通常,当我打开文件时,我从不调用该方法,也不会发生任何不良情况。但是有人告诉我这是不好的做法。这是为什么? 问题答案: 在大多数情况下,不关闭文件是一个坏主意,原因如下: 它会将您的程序放在垃圾收集器的手中-尽管 理论上 该文件将自动关闭,但可能不会关闭。Python 3和Cpython通常在垃圾收集方面做得相当不错,但并非总是如此,其他变体通常也很烂。 它可能会降低您的程序速度。打开

  • 在我的代码中,在使用非整数(例如17.9)给出年龄值后,我无法捕获异常 另外,我的最终没有打印出来<是否有语法错误??