自动绑定闭包中的范围变量 [英] Auto-bind scope variables in a closure
问题描述
考虑这个(而不是无意义的)JavaScript代码:
Consider this (rather pointless) javascript code:
function make_closure() {
var x = 123, y = 456;
return function(varname) { return eval(varname) }
}
closure = make_closure()
closure("x") // 123
closure("y") // 456
不包含对作用域变量的任何引用,但仍可以在调用时返回其值。
The function returned from make_closure
doesn't contain any references to scope variables, but still is able to return their values when called.
有办法同样在python?
Is there a way to do the same in python?
def make_closure():
x = 123
return lambda varname: ...no "x" here...
closure = make_closure()
print closure("x") # 123
换句话说,如何编写一个闭包,在定义范围内知道变量,而不明确提及它们?
In other words, how to write a closure that would "know" about variables in defining scope without mentioning them explicitly?
推荐答案
这可能是一个确切的等价物最接近的事情:
This is probably the closest thing to an exact equivalent:
def make_closure():
x = 123
l = locals()
return lambda(varname): eval(varname, None, l)
closure = make_closure()
print closure("x") # 123
最后,你的问题不是x wasn'
Ultimately, your problem isn't that x wasn't captured by your local closure, but that your local scope wasn't passed into eval.
请参阅 http://docs.python.org/library/functions.html#eval 了解eval函数的详细信息。
See http://docs.python.org/library/functions.html#eval for details on the eval function.
这可能不用说,这不是一个非常Pythonic的事情。你几乎从来不想在Python中调用eval;如果你认为你做了,退后一步,重新思考你的更大的设计。但是当你需要使用它,你需要了解它是如何与JavaScript eval不同。它最终更强大 - 它可以用于模拟动态范围,或者作为exec的简化版本,或者在任意构造的环境中评估代码 - 但这也意味着它更棘手。
It probably goes without saying that this is not a very Pythonic thing to do. You almost never actually want to call eval in Python; if you think you do, step back and rethink your larger design. But when you do need to use it, you need to understand how it's different from Javascript eval. It's ultimately more powerful—it can be used to simulate dynamic scoping, or as a simplified version of exec, or to evaluate code in any arbitrarily-constructed environment—but that also means it's trickier.
这篇关于自动绑定闭包中的范围变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!