gpt4 book ai didi

Python for循环初始化对函数的引用

转载 作者:太空宇宙 更新时间:2023-11-04 03:34:29 25 4
gpt4 key购买 nike

我有这个示例代码,我希望它打印当前的 test.x 变量,但是当我使用 for 循环定义函数引用列表时,我没有得到我期望的结果([1,1]和 [0,0])。当我改用注释行([0,1] 和 [1,0])时,我确实得到了我期望的结果。我意识到有更简单的方法可以做到这一点,但对于我的程序,我需要它是这样的,但我想在 for 循环中定义规则对象,而不是在一行中定义每个元素,因为我不知道如何规则对象将很大。感谢您的帮助(Python 2.7)

class TestClass:
def __init__(self):
self.x = list([0, 1])
def get_value(self, i):
return self.x[i]

test = TestClass()
rules = list([None, None])
for a in range(2):
rules[a] = lambda t: test.get_value(a)
#rules[0] = lambda t: test.get_value(0)
#rules[1] = lambda t: test.get_value(1)

print(rules[0](0), rules[1](0))
test.x[0] = 1
test.x[1] = 0
print(rules[0](0), rules[1](0))

最佳答案

问题可以更简洁地表示如下:

>>> rules = list([None, None])
>>> for a in range(2):
... rules[a] = lambda t: a
...
>>> rules[0](0)
1
>>> rules[0](1)
1
>>> rules[1](0)
1
>>> rules[1](1)
1

我认为问题在于代码总是反射(reflect) a 的最终值。

这被称为“后期绑定(bind)闭包”,在 Python Guide here 中进行了讨论。 .

解决这个问题的一种(相当丑陋的)方法是每次使用 functools 包部分应用一个函数来创建新函数。这会“捕获”a 的当前值。

>>> from functools import partial
>>> for a in range(2):
... def get(t,x): return x
... rules[a] = partial(get,x=a)
...
>>> rules[0](0)
0
>>> rules[0](1)
0
>>> rules[1](0)
1
>>> rules[1](1)
1

实现相同效果的更简单方法:

>>> for a in range(2):
... rules[a] = lambda t,a=a: a

如链接的 Python 指南中所示,您还可以使用列表理解来稍微简化代码:

rules = [lambda t,a=a: a for a in range(2)]

关于Python for循环初始化对函数的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29765878/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com