与X语言关闭相比,Python有什么限制?
其中X是支持某些闭包的编程语言(C#,Javascript,Lisp,Perl,Ruby,Scheme等)。
Python中的闭包(与Ruby的闭包相比)中提到了一些限制,但是这篇文章比较陈旧,并且现代Python中不再存在很多限制。
看到具体限制的代码示例会很好。
相关问题 :
目前最重要的限制是您无法分配给外部变量。 换句话说,闭包是只读的:
>>> 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
我看到人们遇到的唯一困难就是当他们尝试将非功能性功能(如变量重新分配和闭包)混合在一起,并且在这种情况下无法工作时感到惊讶:
def outer ():
x = 1
def inner ():
print x
x = 2
return inner
outer () ()
通常只是指出一个函数有其自己的局部变量足以阻止这种愚蠢。
与Javascript关闭相比,Python关闭的限制(或“限制”)是它不能用于有效的数据隐藏
使用Javascript
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]
链接地址: http://www.djcxy.com/p/1453.html
上一篇: What limitations have closures in Python compared to language X closures?