读/写Python闭包

闭包是一种非常有用的语言功能。他们让我们做一些聪明的事情,这些事情本来需要很多代码,并且常常使我们能够编写更优雅,更清晰的代码。在Python 2.x中,闭包变量名不能反弹。也就是说,在另一个词法范围内定义的函数无法some_var = 'changed!'对其局部范围外的变量执行类似的操作。有人可以解释为什么吗?在某些情况下,我想创建一个在外部范围内重新绑定变量的闭包,但这是不可能的。我意识到,几乎在所有情况下(如果不是全部),这种行为都可以通过类来实现,但是它通常不那么简洁。为什么不能通过封闭方式进行?


这是重新绑定闭包的示例:


def counter():

    count = 0

    def c():

        count += 1

        return count

    return c

调用时,这是当前行为:


>>> c()

Traceback (most recent call last):

  File "<stdin>", line 1, in <module>

  File "<stdin>", line 4, in c

UnboundLocalError: local variable 'count' referenced before assignment

我想要它做的是这样的:


>>> c()

1

>>> c()

2

>>> c()

3


GCT1015
浏览 270回答 3
3回答

万千封印

您可以这样做,它或多或少会以相同的方式工作:class counter(object):&nbsp; &nbsp; def __init__(self, count=0):&nbsp; &nbsp; &nbsp; &nbsp; self.count = count&nbsp; &nbsp; def __call__(self):&nbsp; &nbsp; &nbsp; &nbsp; self.count += 1&nbsp; &nbsp; &nbsp; &nbsp; return self.count&nbsp; &nbsp;&nbsp;或者,有点hack:def counter():&nbsp; &nbsp; count = [0]&nbsp; &nbsp; def incr(n):&nbsp; &nbsp; &nbsp; &nbsp; n[0] += 1&nbsp; &nbsp; &nbsp; &nbsp; return n[0]&nbsp; &nbsp; return lambda: incr(count)我会选择第一个解决方案。编辑:这就是我不阅读文本大博客所得到的。无论如何,Python闭包相当有限的原因是“因为Guido感到喜欢”。Python是在90年代初期(即OO鼎盛时期)设计的。在人们想要的语言功能列表中,闭包率相当低。随着诸如一流函数,闭包之类的功能思想逐渐成为主流,诸如Python之类的语言不得不加以坚持,因此它们的使用可能有点尴尬,因为这不是该语言的设计目的。<rant on="Python scoping">另外,Python(2.x)在范围界定方面有很多奇怪的想法(在我看来),它们影响了闭包的合理实现等。它总是让我感到困扰:new = [x for x in old]x在我们使用的范围内给我们定义名称,因为它(在我看来)是概念上较小的范围。(尽管Python获得了一致性点,因为使用for循环执行相同的操作具有相同的行为。避免这种情况的唯一方法是使用map。)无论如何, </rant>

慕运维8079593

我会使用发电机:>>> def counter():&nbsp; &nbsp; count = 0&nbsp; &nbsp; while True:&nbsp; &nbsp; &nbsp; &nbsp; count += 1&nbsp; &nbsp; &nbsp; &nbsp; yield(count)>>> c = counter()>>> c.next()1>>> c.next()2>>> c.next()3编辑:我相信您的问题的最终答案是PEP-3104:在大多数支持嵌套作用域的语言中,代码可以引用或重新绑定(分配给)最近的封闭作用域中的任何名称。当前,Python代码可以在任何封闭范围内引用名称,但只能在两个范围内重新绑定名称:本地范围(通过简单分配)或模块全局范围(使用全局声明)。在Python-Dev邮件列表和其他地方已经多次提出了此限制,并且导致了扩展讨论和许多关于消除此限制的方法的建议。该PEP总结了已提出的各种备选方案,以及每种方案的优缺点。在2.1版之前,Python对范围的处理类似于标准C的处理:在文件中,只有两个级别的范围:全局和局部。在C语言中,这是自然的结果,因为函数定义不能嵌套。但是在Python中,尽管函数通常是在顶层定义的,但是函数定义可以在任何地方执行。这使Python看起来没有嵌套语义的嵌套作用域的语法外观,并产生了一些程序员惊讶的不一致之处-例如,在顶层使用的递归函数在移入另一个函数时将停止工作,因为递归函数的自己的名字在其范围内将不再可见。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python