gpt4 book ai didi

python - 这个闭包有没有更 'pythonic'的写法?

转载 作者:太空宇宙 更新时间:2023-11-04 10:04:03 26 4
gpt4 key购买 nike

在 JavaScript 中我可能会写这样一个函数:

function counter() {
foo = 0;
function increment() {
foo += 1
console.log(foo);
}
function printVal() {
console.log(foo);
}

return {
increment: increment,
printVal: printVal,
}
}

func = counter();

func.increment()
func.increment()
func.printVal()

我想尝试用python实现类似的功能。特别是我如何通过外部函数的返回访问两个内部函数。

这是一个有效但看起来很有趣的 python 版本:

def counter():
foo = {'bar': 0}
def increment():
foo['bar'] += 1
return foo['bar']
def printVal():
return foo['bar']
return {'increment': increment, 'printVal': printVal}

func = counter()
func['increment']()
func['printVal']()

是否有某种更优雅或“pythonic”的方式来编写这样的闭包?

最佳答案

Python 在闭包方面不如其他语言强大。首先,它只支持读取“关闭”的变量,其次,return 语句让它有点笨拙。

另一方面,类非常简洁,所以如果你想要一个具有两个函数的数据成员,我会用类来实现:

class Counter:
def __init__(self, c=0):
self.count = c
def increment(self):
self.count += 1
def printVal(self):
return self.count


c = Counter()
c.increment()
print(c.printVal())

我敢说在这种情况下,这将是 Pythonic 方式。

编辑

在看到您关于跟踪函数调用的评论后,我添加了这个。你可以通过一个闭包来实现它,就像这样:

# this is the tracked function
def add2(a, b):
return a + b

# this is the count tracker
def counterize(func):
c = [0]
def counter_func(*args, **kw):
c[0] += 1
counter_func.count = c[0]
return func(*args, **kw)
return counter_func


cadd2 = counterize(add2)

print(cadd2(1, 2))
print(cadd2(3, 4))
print('Called %s times' % cadd2.count)

>>>
3
7
Called 2 times

但这在 Python 中不是惯用的。将 count 保留在函数对象中也是一个不错的技巧,但事实就是如此。一个恶作剧。另一方面,在 LISP 或 Scala 中,闭包会更自然,但是,我认为不可能将 count 保留为一个字段,而是将它与结果。

我要说的是,在这种情况下,惯用的 Python 代码将通过类,它更容易理解 IMO 并且代码长度相同:

class Counterize:
def __init__(self, func):
self.func = func
self.count = 0
def __call__(self, *args, **kwargs):
self.count += 1
return self.func(*args, **kwargs)


cadd2 = Counterize(add2)
print(cadd2(1, 2))
print(cadd2(3, 4))
print('Called %s times' % cadd2.count)

输出是一样的。 __call__ 的目的是允许通过带括号的调用将对象视为函数。

关于python - 这个闭包有没有更 'pythonic'的写法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41931698/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com