读/写Python闭包 [英] Read/Write Python Closures

查看:123
本文介绍了读/写Python闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Closures are an incredibly useful language feature. They let us do clever things that would otherwise take a lot of code, and often enable us to write code that is more elegant and more clear. In Python 2.x, closures variable names cannot be rebound; that is, a function defined inside another lexical scope cannot do something like some_var = 'changed!' for variables outside of its local scope. Can someone explain why that is? There have been situations in which I would like to create a closure that rebinds variables in the outer scope, but it wasn't possible. I realize that in almost all cases (if not all of them), this behavior can be achieved with classes, but it is often not as clean or as elegant. Why can't I do it with a closure?

以下是重新绑定关闭的示例:

Here is an example of a rebinding closure:

def counter():
    count = 0
    def c():
        count += 1
        return count
    return c

这是您调用它时的当前行为:

This is the current behavior when you call it:

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


推荐答案

Ignacio的回答:

To expand on Ignacio's answer:

def counter():
    count = 0
    def c():
        nonlocal count
        count += 1
        return count
    return c

x = counter()
print([x(),x(),x()])

counter()的调用赋予独立计数器。其他解决方案 - 特别是使用 itertools / yield 更为惯用。

gives [1,2,3] in Python 3; invocations of counter() give independent counters. Other solutions - especially using itertools/yield are more idiomatic.

这篇关于读/写Python闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆