在关闭自动绑定变量的作用域(Auto-bind scope variables in a closu

2019-09-18 06:59发布

考虑这个(相当无意义)的JavaScript代码:

function make_closure() {
    var x = 123, y = 456;
    return function(varname) { return eval(varname) }
}

closure = make_closure()
closure("x") // 123
closure("y") // 456

从返回的功能make_closure不包含范围变量的任何引用,但仍然能够调用时返回它们的值。

有没有办法做同样的蟒蛇?

def make_closure():
    x = 123
    return lambda varname: ...no "x" here...

closure = make_closure()
print closure("x") # 123

换句话说,如何写关闭,将“知道”定义范围没有明确提到他们的变量?

Answer 1:

这可能是最接近完全等效:

def make_closure():
  x = 123
  l = locals()
  return lambda(varname): eval(varname, None, l)

closure = make_closure()
print closure("x") # 123

最终,你的问题不在于X不是由当地的封闭拍摄,但当地的范围并没有传递到EVAL。

见http://docs.python.org/library/functions.html#eval有关eval函数的详细信息。

它可能不用说,这是不是做了非常Python化的事情。 你几乎从来没有真正想调用EVAL在Python; 如果你认为你这样做,退一步,重新审视自己的更大的设计。 但是,当你需要使用它,你需要了解它是如何从Javascript的eval不同。 它的最终功能更强大,它可以被用来模拟动态作用域,或作为EXEC的简化版本,或以任何任意构造的评估代码环境,但是这也意味着它是棘手。



Answer 2:

利用人们已经提到locals() 另外,诚然不太灵活,方法是使用新的nonlocal关键词在Python 3:

>>> def make_closure():
...     x = 123
...     def return_var(varname):
...         nonlocal x
...         return eval(varname)
...     return return_var
... 
>>> closure = make_closure()
>>> closure("x")
123

这有需要你明确地标注来自外部范围,你要关闭了,并引用变量的明显缺点。



Answer 3:

您可以紧密围绕变量在Python中,大约你如何在Javascript将:

def foo():
  x = 123
  return lambda y: x+y

q = foo()

print q(5)

http://ideone.com/Q8iBg

不过,也有一定的差异 - 例如,你可以不写在父母的范围变量(试图只写创建一个局部范围的变量来代替)。 此外,Python的eval()不包括父范围。

您可以绕过此为eval()通过明确从父范围抓住了当地人并将它们传递到孩子eval()作为它的当地人的说法,但这里真正的问题是,为什么你要这么做?



Answer 4:

在Python 2.x的,这需要一些大规模kludging。 然而,在Python 3.X的“外地”的关键字被引入到允许访问的变量直接封闭范围。

这可能是值得检查这里了解更多信息: 在Python 2.x的外地关键字



文章来源: Auto-bind scope variables in a closure