您如何向知道其所包含概念的人(例如函数,变量等)解释JavaScript闭包,但不了解闭包本身?
我已经看过维基百科上给出的Scheme示例,但遗憾的是它并没有帮助.
我问了一个关于Currying和关闭的问题.什么是关闭?它与currying有什么关系?
computer-science glossary functional-programming terminology
我一直在阅读很多关于闭包的内容,我认为我理解它们,但是没有为自己和他人蒙上阴影,我希望有人可以尽可能简洁明了地解释闭包.我正在寻找一个简单的解释,可以帮助我理解我想要使用它们的地点和原因.
这一点Python不起作用:
def make_incrementer(start):
def closure():
# I know I could write 'x = start' and use x - that's not my point though (:
while True:
yield start
start += 1
return closure
x = make_incrementer(100)
iter = x()
print iter.next() # Exception: UnboundLocalError: local variable 'start' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
我知道如何解决这个错误,但请耐心等待:
这段代码工作正常:
def test(start):
def closure():
return start
return closure
x = test(999)
print x() # prints 999
Run Code Online (Sandbox Code Playgroud)
为什么我可以读取start闭包内的变量而不是写入它?导致这种start变量处理的语言规则是什么?
更新:我发现这个SO帖子相关(答案不仅仅是问题):读/写Python闭包
有pythonic没有完全面向对象的方法来维护状态(例如,为了优化的目的)?
为了更好地说明我的问题,这里是我在JavaScript中经常使用的模式的示例:
var someFunc = (function () {
var foo = some_expensive_initialization_operation();
return someFunc (bar) {
// do something with foo and bar
}
}());
Run Code Online (Sandbox Code Playgroud)
在外部,这只是一个像其他任何函数一样的函数,不需要初始化对象或类似的东西,但闭包允许计算值一次,然后我基本上用作常量.
Python中的一个例子是优化正则表达式 - 使用re.compile和存储编译版本match和search操作很有用.
我知道在Python中执行此操作的唯一方法是在模块范围中设置变量:
compiled_regex = compile_my_regex()
def try_match(m): # In reality I wouldn't wrap it as pointlessly as this
return compiled_regex.match(m)
Run Code Online (Sandbox Code Playgroud)
或者通过创建一个类:
class MatcherContainer(object):
def __init__(self):
self.compiled_regex = compile_my_regex()
def try_match(self, m):
self.compiled_regex.match(m)
my_matcher = MatcherContainer()
Run Code Online (Sandbox Code Playgroud)
前一种方法是临时的,并且不清楚上面声明的函数和变量是否相互关联.它也会污染模块的命名空间,我对此并不满意.
后一种方法似乎冗长而且在样板上有点沉重.
我能想到的另一种处理方法是将这样的任何函数分解为单独的文件(模块),然后导入函数,以便一切都干净.
来自更有经验的Pythoners的任何建议如何处理这个?或者你只是不担心它并继续解决问题?
我刚刚学习了python @ decorator,很酷,但很快我就发现修改后的代码出现了奇怪的问题.
def with_wrapper(param1):
def dummy_wrapper(fn):
print param1
param1 = 'new'
fn(param1)
return dummy_wrapper
def dummy():
@with_wrapper('param1')
def implementation(param2):
print param2
dummy()
Run Code Online (Sandbox Code Playgroud)
我调试它,它在print param1抛出异常
UnboundLocalError: local variable 'param1' referenced before assignment
Run Code Online (Sandbox Code Playgroud)
如果我删除 param1 = 'new'此行,而没有对外部作用域的变量进行任何修改操作(链接到新对象),则此例程可能会起作用.
这是否意味着我只制作了一个外部范围变量的副本,然后进行修改?
感谢Delnan,关闭是必不可少的.可能从这里回答: 与语言X闭包相比,Python中的闭包有哪些限制?
类似的代码:
def e(a):
def f():
print a
a = '1'
f()
e('2')
Run Code Online (Sandbox Code Playgroud)
而且这似乎是以前讨厌的全局变量:
a = '1'
def b():
#global a
print a
a = '2'
b()
Run Code Online (Sandbox Code Playgroud)
这是通过添加全局符号来修复的.但是为了关闭,没有找到这样的符号.谢谢unutbu,Python 3给了我们非本地化.
我从上面知道直接访问外部变量是只读的.但是看到先前读取变量(print var)也受到影响有点不舒服.
我想知道Python中的闭包是否可以操作其命名空间中的变量.你可能会称这种副作用,因为状态在闭包本身之外被改变了.我想做这样的事情
def closureMaker():
x = 0
def closure():
x+=1
print x
return closure
a = closureMaker()
a()
1
a()
2
Run Code Online (Sandbox Code Playgroud)
显然我希望做的更复杂,但这个例子说明了我在说什么.
我有这个代码:
import re
def doReplace(toReplace):
i = 1
def chapterReplacer(_):
result = 'Chapter %i' % i
i += 1
return result
return re.sub('Chapter [a-zA-Z]+', chapterReplacer, test)
test = 'Chapter one Chapter Two Chapter three'
print doReplace(test)
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我收到以下错误:
Traceback (most recent call last):
File "C:/Python26/replace.py", line 13, in <module>
print doReplace(test)
File "C:/Python26/replace.py", line 10, in doReplace
return re.sub('Chapter [a-zA-Z]+', chapterReplacer, test)
File "C:\Python26\lib\re.py", line 151, in sub
return _compile(pattern, 0).sub(repl, string, count)
File "C:/Python26/replace.py", line 6, in chapterReplacer
result = …Run Code Online (Sandbox Code Playgroud) 我基本上需要的是一个可变整数,它可以完成下面的等价,而不必求助于使用单个元素列表.
下面是一个人为的代码示例,它代表了我实际用例的本质[1]
>>> a = [5]
>>> b = [77]
>>> def swap(num1, num2):
... temp = num1[0]
... num1[0] = num2[0]
... num2[0] = temp
>>> swap(a, b)
>>> a
[77]
>>> b
[5]
Run Code Online (Sandbox Code Playgroud)
[1]我的实际用例更接近于这一点 - >
在Tkinter中使用按钮调用函数后返回一个值
我需要从与Tkinter小部件关联的回调函数返回一个值,我想避免使用全局变量.
closures ×7
python ×7
decorator ×1
function ×1
generator ×1
glossary ×1
integer ×1
javascript ×1
mutable ×1
scope ×1
side-effects ×1
state ×1
terminology ×1
variables ×1