Python用户完全可以合理地质疑,为什么不能写成下面这样:
def foo (n):
return lambda i: return n += i
return lambda i: return n += i
或者:
def foo (n):
lambda i: n += i
lambda i: n += i
我猜想,Python有一天会支持这样的写法。(如果你不想等到Python慢慢进化到更像Lisp,你总是可以直接......)
在面向对象编程的语言中,你能够在有限程度上模拟一个闭包(即一个函数,通过它可以引用由包含这个函数的代码所定义的变量)。你定义一个类(class),里面有一个方法和一个属性,用于替换封闭作用域(enclosing scope)中的所有变量。这有点类似于让程序员自己做代码分析,本来这应该是由支持局部作用域的编译器完成的。如果有多个函数,同时指向相同的变量,那么这种方法就会失效,但是在这个简单的例子中,它已经足够了。
Python高手看来也同意,这是解决这个问题的比较好的方法,写法如下:
def foo (n):
class acc:
def _ _init_ _ (self, s):
self.s = s
def inc (self, i):
self.s += i
return self.s
return acc (n).inc
class acc:
def _ _init_ _ (self, s):
self.s = s
def inc (self, i):
self.s += i
return self.s
return acc (n).inc
或者
class foo:
def _ _init_ _ (self, n):
self.n = n
def _ _call_ _ (self, i):
self.n += i
return self.n
def _ _init_ _ (self, n):
self.n = n
def _ _call_ _ (self, i):
self.n += i
return self.n
我添加这一段,原因是想避免Python爱好者说我误解这种语言。但是,在我看来,这两种写法好像都比第一个版本更复杂。你实际上就是在做同样的事,只不过划出了一个独立的区域,保存累加器函数,区别只是保存在对象的一个属性中,而不是保存在列表(list)的头(head)中。使用这些特殊的内部属性名(尤其是__call__),看上去并不像常规的解法,更像是一种破解。