Python相比语言X闭包有什么限制? [英] What limitations have closures in Python compared to language X closures?

查看:120
本文介绍了Python相比语言X闭包有什么限制?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



关闭在Python 中(与Ruby的闭包相比),但是文章很旧,现代Python中不再存在许多限制。



查看代码示例

相关问题




解决方案

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

 >>> def outer(x):
... def inner_reads():
...#将返回outer的'x'。
... return x
... def inner_writes(y):
...#将分配给本地'x',而不是外部'x'
。 .. x = y
... def inner_error(y):
...#会产生错误:'x'是局部的,因为赋值,
...#我们在它被分配到之前使用它。
... 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
>>>>内部错误(10)
跟踪(最近最后调用):
在< module>中的文件< stdin&
文件< stdin>,第11行,在inner_error中
UnboundLocalError:局部变量'x'在赋值前引用

在本地作用域(函数)中赋值的名称总是局部的,除非另有声明。虽然有一个全局声明来声明一个变量global,即使它被赋值,但没有这样的声明为封闭变量 - 。在Python 3.0中,有(非)本地的声明。



你可以通过使用可变容器来解决这个限制类型:

 >>> def outer(x):
... x = [x]
... def inner_reads():
...#将返回outer的x的第一个
... return x [0]
... def inner_writes(y):
...#查找外部的x,然后改变它。
... x [0] = y
... def inner_error(y):
...#现在可以工作了,因为'x'没有赋值,只是引用。
... 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


Where X is any programming language (C#, Javascript, Lisp, Perl, Ruby, Scheme, etc) which supports some flavour of closures.

Some limitations are mentioned in the Closures in Python (compared to Ruby's closures), but the article is old and many limitations do not exist in modern Python any more.

Seeing a code example for a concrete limitation would be great.

Related questions:

解决方案

The most important limitation, currently, is that you cannot assign to an outer-scope variable. In other words, closures are read-only:

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

A name that gets assigned to in a local scope (a function) is always local, unless declared otherwise. While there is the 'global' declaration to declare a variable global even when it is assigned to, there is no such declaration for enclosed variables -- yet. In Python 3.0, there is (will be) the 'nonlocal' declaration that does just that.

You can work around this limitation in the mean time by using a mutable container type:

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

这篇关于Python相比语言X闭包有什么限制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆