简体   繁体   English

有没有一种 Pythonic 的方法来关闭循环变量?

[英]Is there a Pythonic way to close over a loop variable?

I just ran across Eric Lippert's Closing over the loop variable considered harmful via SO, and, after experimenting, realized that the same problem exists (and is even harder to get around) in Python.我刚刚遇到了 Eric Lippert 的Closing over the loop variable 被认为是有害的,通过 SO 被认为是有害的,并且在实验之后,意识到在 Python 中存在同样的问题(并且更难解决)。

>>> l = []
>>> for r in range(10):
...   def foo():
...      return r
...   l.append(foo)
...
>>> for f in l:
...   f()
...
9
9
9
# etc

and, the standard C# workaround doesn't work (I assume because of the nature of references in Python)并且,标准的 C# 解决方法不起作用(我假设是因为 Python 中引用的性质)

>>> l = []
>>> for r in range(10):
...   r2 = r
...   def foo():
...      return r2
...   l.append(foo)
...
>>> for f in l:
...   f()
...
9
9
9
# etc

I recognize that this isn't much of a problem in Python with its general emphasis on non-closure object structures, but I'm curious if there is an obvious Pythonic way to handle this, or do we have to go the JS route of nested function calls to create actually new vars?我认识到这在 Python 中并不是什么大问题,因为它普遍强调非闭包对象结构,但是我很好奇是否有明显的 Pythonic 方法来处理这个问题,或者我们是否必须走 JS 路线嵌套函数调用来创建实际的新变量?

>>> l = []
>>> for r in range(10):
...     l.append((lambda x: lambda: x)(r))
...
>>> for f in l:
...     f()
...
0
1
2
# etc

One way is to use a parameter with default value:一种方法是使用具有默认值的参数:

l = []
for r in range(10):
    def foo(r = r):
        return r
    l.append(foo)

for f in l:
    print(f())

yields产量

0
1
2
3
4
5
6
7
8
9

This works because it defines an r in foo 's local scope, and binds the default value to it at the time foo is defined.这个作品,因为它定义了一个rfoo的局部范围,并结合在时间的缺省值给它foo定义。


Another way is to use a function factory:另一种方法是使用函数工厂:

l = []
for r in range(10):
    def make_foo(r):
        def foo():
            return r
        return foo
    l.append(make_foo(r))

for f in l:
    print(f())

This works because it defines r in make_foo 's local scope, and binds a value to it when make_foo(r) is called.这是有效的,因为它在make_foo的本地范围内定义了r ,并在make_foo(r)make_foo(r)绑定一个值。 Later, when f() is called, r is looked-up using the LEGB rule .稍后,当调用f()时,使用LEGB 规则查找r Although r is not found in the local scope of foo , it is found in the enclosing scope of make_foo .尽管rfoo的本地范围内找不到,但在make_foo的封闭范围内make_foo

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM