还有更多的';pythonic';写这个闭包的方法?
在JavaScript中,我可以编写如下函数:还有更多的';pythonic';写这个闭包的方法?,python,closures,Python,Closures,在JavaScript中,我可以编写如下函数: function counter() { foo = 0; function increment() { foo += 1 console.log(foo); } function printVal() { console.log(foo); } return { increment: increment, printVal: printV
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()
# 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实现类似的函数。特别是如何通过外部函数的返回访问两个内部函数
下面是一个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”的方法来编写这样的闭包?只需实现
\uuu getitem\uuuu
class Foo:
class_attributes = {'a': 3,
'b': 5}
def __getitem__(self, name):
return Foo.class_attributes[name]
f = Foo()
print f['a']
输出:
3
只需实现
\uuu getitem\uuuu
class Foo:
class_attributes = {'a': 3,
'b': 5}
def __getitem__(self, name):
return Foo.class_attributes[name]
f = Foo()
print f['a']
输出:
3
我认为您想要实现的是以下示例:
def makeInc(x):
def inc(y):
# x is "attached" in the definition of inc
return y + x
return inc
incOne = makeInc(1)
incFive = makeInc(5)
incOne (5) # returns 6
incFive(5) # returns 10
您需要创建闭包的pythonic方法。上面的例子演示了如何做到这一点 我认为您想要实现的是以下示例:
def makeInc(x):
def inc(y):
# x is "attached" in the definition of inc
return y + x
return inc
incOne = makeInc(1)
incFive = makeInc(5)
incOne (5) # returns 6
incFive(5) # returns 10
您需要创建闭包的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())
我敢说,在这种情况下,这将是蟒蛇式的方式
编辑
在看到您关于跟踪函数调用的评论后,我添加了以下内容。您可以通过闭包来实现,如下所示:
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()
# 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中,闭包会更自然,但我认为不可能将计数作为字段,而是将其与结果一起返回
我要说的是,在这种情况下,惯用Python代码也是通过类编写的,在我看来,它更容易理解,并且代码长度相同:
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)
结果是一样的。\uuuu call\uuuu
的目的是允许通过使用括号调用将对象视为函数。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())
我敢说,在这种情况下,这将是蟒蛇式的方式
编辑
在看到您关于跟踪函数调用的评论后,我添加了以下内容。您可以通过闭包来实现,如下所示:
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()
# 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中,闭包会更自然,但我认为不可能将计数作为字段,而是将其与结果一起返回
我要说的是,在这种情况下,惯用Python代码也是通过类编写的,在我看来,它更容易理解,并且代码长度相同:
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)
结果是一样的。\uuuu call\uuuu
的目的是允许通过使用括号调用的方式将对象视为函数。在这种情况下,您可能需要使用集合.计数器
对象,或者只是编写一个类。首先,你应该问问自己为什么要在JS中使用闭包:闭包通常是类行为的替代品。在python的情况下,您确实可以使用类
来建模记帐行为。你的两个函数变成了真正的方法。在这种情况下,你可能想使用集合。Counter
对象,或者只是编写一个类。你应该问问自己,为什么要在JS中使用闭包:闭包通常是类行为的替代品。在python的情况下,您确实可以使用类
来建模记帐行为。你的两个函数都变成了实方法。这里的所有Foo实例都会使用相同的class_属性吗?在本例中会。可以通过实现构造函数来定义每个实例的类\属性。在这里,相同的类\属性会用于所有Foo实例吗?在本例中,会。可以通过实现构造函数来定义每个实例的class_属性。谢谢,我希望使用闭包,因为我正在努力学习更多的函数技术,但这似乎是目前为止最好的解决方案。我想做的更大的事情是有一个计数器,我可以用来跟踪函数被调用的次数。谢谢,我希望使用闭包,因为我正在努力学习更多的函数技术,但这看起来是迄今为止最好的解决方案。我想做的是有一个计数器,可以用来跟踪函数被调用的次数。