与语言X闭包相比,Python中的闭包有哪些限制?

其中X是支持某种闭包形式的任何编程语言(C#,Javascript,Lisp,Perl,Ruby,Scheme等)。


在Python的闭包中(与Ruby的闭包相比)中提到了一些限制,但是该文章过时了,现代的Python中不再存在许多限制。


看到一个代码示例以了解具体的限制会很棒。


GCT1015
浏览 526回答 3
3回答

当年话下

当前,最重要的限制是您不能分配给外部作用域变量。换句话说,闭包是只读的:>>> def outer(x):&nbsp;...&nbsp; &nbsp; &nbsp;def inner_reads():...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Will return outer's 'x'....&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return x...&nbsp; &nbsp; &nbsp;def inner_writes(y):...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Will assign to a local 'x', not the outer 'x'...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x = y...&nbsp; &nbsp; &nbsp;def inner_error(y):...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Will produce an error: 'x' is local because of the assignment,...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# but we use it before it is assigned to....&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tmp = x...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x = y...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return tmp...&nbsp; &nbsp; &nbsp;return inner_reads, inner_writes, inner_error...&nbsp;>>> inner_reads, inner_writes, inner_error = outer(5)>>> inner_reads()5>>> inner_writes(10)>>> inner_reads()5>>> inner_error(10)Traceback (most recent call last):&nbsp; File "<stdin>", line 1, in <module>&nbsp; File "<stdin>", line 11, in inner_errorUnboundLocalError: local variable 'x' referenced before assignment除非另行声明,否则在本地范围(函数)中分配给它的名称始终是本地名称。尽管存在“全局”声明来声明变量全局变量(即使已将其分配给它),但对于封闭变量来说尚无此类声明。在Python 3.0中,有(将有)“ nonlocal”声明可以做到这一点。您可以同时使用可变的容器类型来解决此限制:>>> def outer(x):...&nbsp; &nbsp; &nbsp;x = [x]...&nbsp; &nbsp; &nbsp;def inner_reads():...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Will return outer's x's first (and only) element....&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return x[0]...&nbsp; &nbsp; &nbsp;def inner_writes(y):...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Will look up outer's x, then mutate it.&nbsp; &nbsp; &nbsp;&nbsp;...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x[0] = y...&nbsp; &nbsp; &nbsp;def inner_error(y):...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# Will now work, because 'x' is not assigned to, just referenced....&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;tmp = x[0]...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;x[0] = y...&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return tmp...&nbsp; &nbsp; &nbsp;return inner_reads, inner_writes, inner_error...&nbsp;>>> inner_reads, inner_writes, inner_error = outer(5)>>> inner_reads()5>>> inner_writes(10)>>> inner_reads()10>>> inner_error(15)10>>> inner_reads()15

米脂

与Javascript闭包相比,Python闭包的局限性(或“局限性”)是它不能用于有效的数据隐藏Java脚本var mksecretmaker = function(){&nbsp; &nbsp; var secrets = [];&nbsp; &nbsp; var mksecret = function() {&nbsp; &nbsp; &nbsp; &nbsp; secrets.push(Math.random())&nbsp; &nbsp; }&nbsp; &nbsp; return mksecret}var secretmaker = mksecretmaker();secretmaker(); secretmaker()// privately generated secret number list// is practically inaccessible蟒蛇import randomdef mksecretmaker():&nbsp; &nbsp; secrets = []&nbsp; &nbsp; def mksecret():&nbsp; &nbsp; &nbsp; &nbsp; secrets.append(random.random())&nbsp; &nbsp; return mksecretsecretmaker = mksecretmaker()secretmaker(); secretmaker()# "secrets" are easily accessible,# it's difficult to hide something in Python:secretmaker.__closure__[0].cell_contents # -> e.g. [0.680752847190161, 0.9068475951742101]

MM们

我见过的人们特别遇到的唯一困难是,当他们尝试将诸如变量重新分配之类的非功能性功能与闭包混合在一起时,当它们无法正常工作时,他们会感到惊讶:def outer ():&nbsp; &nbsp; x = 1&nbsp; &nbsp; def inner ():&nbsp; &nbsp; &nbsp; &nbsp; print x&nbsp; &nbsp; &nbsp; &nbsp; x = 2&nbsp; &nbsp; return innerouter () ()通常只需指出一个函数具有其自己的局部变量就足以阻止这种愚蠢的行为。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python