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

Why can't Python increment variable in closure?

错误消息是不言而喻的。我在这里提供了一些解决方案。使用函数属性(不常见,但效果很好)

对nonlocal使用闭包(理想,但仅限Python 3)

在可变对象上使用闭包(Python 2的习惯用法)

对自定义对象使用方法

通过实现__call__直接调用对象的实例

对函数使用属性

创建函数后,手动为其设置计数器属性:def foo():

foo.counter += 1

return foo.counter

foo.counter = 0

现在:>>> foo()

1

>>> foo()

2

>>> foo()

3

或者您可以自动设置功能:def foo():

if not hasattr(foo, 'counter'):

foo.counter = 0

foo.counter += 1

return foo.counter

同样地:>>> foo()

1

>>> foo()

2

>>> foo()

3

这些方法很简单,但并不常见,而且不太可能在没有您在场的情况下被查看您的代码的人快速搜索到。

根据Python版本的不同,您希望完成的更常见的方法也有所不同。

Python 3,使用带nonlocal的闭包

在Python 3中,可以声明非本地:def foo():

counter = 0

def bar():

nonlocal counter

counter += 1

print("bar", counter)

return bar

bar = foo()

它会增加>>> bar()

bar 1

>>> bar()

bar 2

>>> bar()

bar 3

这可能是解决这个问题最惯用的方法。可惜只限于Python 3。

Python 2非本地解决方案:

您可以声明一个全局变量,然后在其上递增,但这会使模块名称空间变得混乱。因此,避免声明全局变量的惯用方法是指向包含要递增的整数的可变对象,这样就不会尝试重新分配变量名:def foo():

counter = [0]

def bar():

counter[0] += 1

print("bar", counter)

return bar

bar = foo()

现在:>>> bar()

('bar', [1])

>>> bar()

('bar', [2])

>>> bar()

('bar', [3])

我认为这比创建类来保存递增变量的建议要好。但为了完整起见,让我们看看。

使用自定义对象class Foo(object):

def __init__(self):

self._foo_call_count = 0

def foo(self):

self._foo_call_count += 1

print('Foo.foo', self._foo_call_count)

foo = Foo()

现在:>>> foo.foo()

Foo.foo 1

>>> foo.foo()

Foo.foo 2

>>> foo.foo()

Foo.foo 3

甚至实现__call__:class Foo2(object):

def __init__(self):

self._foo_call_count = 0

def __call__(self):

self._foo_call_count += 1

print('Foo', self._foo_call_count)

foo = Foo2()

现在:>>> foo()

Foo 1

>>> foo()

Foo 2

>>> foo()

Foo 3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>