为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

GCT1015 2019-11-12 11:15:40
其中X是支持某种闭包形式的任何编程语言(C#,Javascript,Lisp,Perl,Ruby,Scheme等)。在Python的闭包中(与Ruby的闭包相比)中提到了一些限制,但是该文章过时了,现代的Python中不再存在许多限制。看到一个代码示例以了解具体的限制会很棒。
查看完整描述

3 回答

?
当年话下

TA贡献1890条经验 获得超9个赞

当前,最重要的限制是您不能分配给外部作用域变量。换句话说,闭包是只读的:


>>> def outer(x): 

...     def inner_reads():

...         # Will return outer's 'x'.

...         return x

...     def inner_writes(y):

...         # Will assign to a local 'x', not the outer 'x'

...         x = y

...     def inner_error(y):

...         # Will produce an error: 'x' is local because of the assignment,

...         # but we use it before it is assigned to.

...         tmp = x

...         x = y

...         return tmp

...     return inner_reads, inner_writes, inner_error

... 

>>> 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):

  File "<stdin>", line 1, in <module>

  File "<stdin>", line 11, in inner_error

UnboundLocalError: local variable 'x' referenced before assignment

除非另行声明,否则在本地范围(函数)中分配给它的名称始终是本地名称。尽管存在“全局”声明来声明变量全局变量(即使已将其分配给它),但对于封闭变量来说尚无此类声明。在Python 3.0中,有(将有)“ nonlocal”声明可以做到这一点。


您可以同时使用可变的容器类型来解决此限制:


>>> def outer(x):

...     x = [x]

...     def inner_reads():

...         # Will return outer's x's first (and only) element.

...         return x[0]

...     def inner_writes(y):

...         # Will look up outer's x, then mutate it.      

...         x[0] = y

...     def inner_error(y):

...         # Will now work, because 'x' is not assigned to, just referenced.

...         tmp = x[0]

...         x[0] = y

...         return tmp

...     return inner_reads, inner_writes, inner_error

... 

>>> inner_reads, inner_writes, inner_error = outer(5)

>>> inner_reads()

5

>>> inner_writes(10)

>>> inner_reads()

10

>>> inner_error(15)

10

>>> inner_reads()

15


查看完整回答
反对 回复 2019-11-12
?
米脂

TA贡献1836条经验 获得超3个赞

与Javascript闭包相比,Python闭包的局限性(或“局限性”)是它不能用于有效的数据隐藏


Java脚本

var mksecretmaker = function(){

    var secrets = [];

    var mksecret = function() {

        secrets.push(Math.random())

    }

    return mksecret

}

var secretmaker = mksecretmaker();

secretmaker(); secretmaker()

// privately generated secret number list

// is practically inaccessible

蟒蛇

import random

def mksecretmaker():

    secrets = []

    def mksecret():

        secrets.append(random.random())

    return mksecret


secretmaker = 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]


查看完整回答
反对 回复 2019-11-12
?
MM们

TA贡献1886条经验 获得超2个赞

我见过的人们特别遇到的唯一困难是,当他们尝试将诸如变量重新分配之类的非功能性功能与闭包混合在一起时,当它们无法正常工作时,他们会感到惊讶:


def outer ():

    x = 1

    def inner ():

        print x

        x = 2

    return inner

outer () ()

通常只需指出一个函数具有其自己的局部变量就足以阻止这种愚蠢的行为。


查看完整回答
反对 回复 2019-11-12
  • 3 回答
  • 0 关注
  • 520 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信