Assign variable to local scope of function in Python
我想给一个lambda的作用域分配一个变量,这个lambda被多次调用。每次都有一个新的变量实例。我该怎么做?
1 2 3 4 5
| f = lambda x: x + var.x - var.y
# Code needed here to prepare f with a new var
result = f(10) |
在本例中,它是var,我希望在每次调用时都替换它,而不将其作为第二个参数。
- 不要使用lambda,使用常规函数,你不应该觉得有必要尽可能使用lambda。
- 一般来说,如果lambda足够复杂,以至于您必须询问如何扭曲它来完成任务,那么只需使用常规的"def"函数即可。它将使代码更可读、更可维护。
- @我同意。但是lambda或者正则函数,我不确定OP是如何完成他所要求的。在不使用参数的情况下,如何更改函数范围内的某些内容?
- 如果这有帮助,可以用常规函数替换lambda。我只需要以某种方式操作函数局部变量/闭包。
- 如何在python中修改本地名称空间或如何动态修改函数的本地名称空间的可能副本?@JonathonReinhart有几种方法,但在那些链接中看不到干净的方法。
- @正在引用命名空间的Jamyak。这真的适用于函数范围的变量吗?
- @JonathonReinhart是的,另外Op规定他不能在lambda定义中添加另一个参数,因此没有其他方法
- @查米拉克,对。整个事情开始显得荒谬起来。
- lambda是在外部定义的,超出了我的控制范围,但我想为lambda创建者提供一个范围。这样做更有意义吗?
在lambda的作用域中未定义的变量是从调用它的点的调用作用域中解析出来的。
一个稍微简单的例子…
1 2 3 4 5 6 7
| >>> y = 1
>>> f = lambda x: x + y
>>> f(1)
2
>>> y = 2
>>> f(1)
3 |
…所以,在调用你的lambda之前,你只需要在调用范围中设置var,尽管在y是"常量"的情况下,这更常用。
该函数的反汇编显示…
1 2 3 4 5 6
| >>> import dis
>>> dis.dis(f)
1 0 LOAD_FAST 0 (x)
3 LOAD_GLOBAL 0 (y)
6 BINARY_ADD
7 RETURN_VALUE |
。
如果您想在定义lambda时将y绑定到一个对象(即创建一个闭包),通常会看到这个习语…
1 2 3 4 5 6 7
| >>> y = 1
>>> f = lambda x, y=y: x + y
>>> f(1)
2
>>> y = 2
>>> f(1)
2 |
…因此,在定义lambda后,对y的更改没有效果。
该函数的反汇编显示…
1 2 3 4 5 6
| >>> import dis
>>> dis.dis(f)
1 0 LOAD_FAST 0 (x)
3 LOAD_FAST 1 (y)
6 BINARY_ADD
7 RETURN_VALUE |
。
- 虽然这很漂亮,而且是手术室的要求,但我为必须保持这一点的可怜的小混蛋感到抱歉。"在这个lambda里,y到底是从哪里来的?!"在本例中可能很明显,但在更大的项目中则不明显。记住python的成语"显式而非隐式"…我不认为这是明确的。
- @乔纳森·莱因哈特,我同意。我主要是因为其他答案暗示这是不可能的,所以我只是想证明这是可能的。这是不是一个好主意是主观的。对于OP想要实现的目标,可能有一个更好的解决方案,但是最初的问题并没有包含足够的信息来做出决定。
f = functools.partial(lambda var, x: x + var.x - var.y, var)将为您提供一个参数(x的函数(f,其中var固定在定义点的值上。
不能在lambda表达式中使用赋值语句,因此必须使用正则命名函数:
1 2 3
| def f(x):
global var
var = x |
号
注意使用"global"关键字。如果没有它,python将假定您想要在函数的本地范围内创建一个新的"var"变量。
- UPS。抱歉,假定您要分配给变量,而不是对象字段。在这种情况下不需要"全局"(因为您没有引入新的绑定)。
- 我不认为使用一个全局来"为一个函数的作用域分配一个变量"。这是一个全局范围的变量。
- 我不确定这对我的案件有什么帮助?
- @jonasklemming如果变量在全局范围内,那么从外部更改它将在任何地方更改它,包括在函数内部。这是个坏主意,但会奏效的。
- 我同意这是一个糟糕的答案。我误解了这个问题。
- 啊,好吧,也许使用全局是一个解决方案。
- 为什么不能在lambda表达式中使用赋值语句?
- 因为赋值只能用作语句,所以它不是有效的表达式。
使其成为另一个参数:
1 2
| f = lambda x,var: x + var.x - var.y
result = f(10, var) |
lambda或正则函数,在函数范围内更改变量的唯一方法是通过参数。
- 谢谢,这是我的第一个想法,但我想避免第二次争吵。
- 那么你还能怎么做呢?如何控制每次调用f时var是什么?
- 我希望有一种方法可以操纵F的关闭
- 在这种情况下,是的,重新定义lambda,每个你想使用它的地方。似乎很傻很费解。(即难以理解、维护等)
- 为什么要避免第二次争吵?如果你想要两个数据,为什么要掩盖它?
- 是的,这不是一个可以接受的解决方案,也许这是不可能的。
- 避免两个参数的原因是第二个参数很少使用,但有些情况下需要它,我希望尽可能地保持lambda的琐碎。
- 好吧,但如果不使用,那么什么是var?这变得如此复杂。也许你需要提供更多的信息/代码来帮助我们理解你到底想做什么。我会考虑删除整个问题并重新开始。
- 不过,谢谢您的意见!