【问题标题】:Assign variable to local scope of function in Python在Python中将变量分配给函数的局部范围
【发布时间】:2013-05-15 08:02:33
【问题描述】:

我想将一个变量分配给多次调用的 lambda 范围。每次都有一个新的变量实例。我该怎么做?

f = lambda x: x + var.x - var.y

# Code needed here to prepare f with a new var

result = f(10)

在这种情况下,我想为每次调用替换 var 而不将其作为第二个参数。

【问题讨论】:

  • 不要使用lambda,使用常规函数,你应该觉得没有必要尽可能使用lambdas
  • 一般来说,如果 lambda 足够复杂,以至于您必须询问如何扭曲它来完成任务,只需使用常规的 'def' 函数。这将导致它的代码更具可读性、可维护性。
  • @jamylak 我同意。但是 lambda 或常规函数,我不确定 OP 想要如何完成他的要求。如何在不使用参数的情况下更改函数范围内的内容?
  • 如果有帮助,您可以将 lambda 替换为常规函数。我只需要以某种方式操纵函数局部变量/闭包。
  • How to modify the local namespace in pythonHow to dynamically modify a function's local namespace? @JonathonReinhart 的可能重复项有几种方法,但在这些链接中没有看到干净的方法

标签: python lambda


【解决方案1】:

lambda 范围内未定义的变量在调用它的位置从调用范围解析。

一个稍微简单的例子……

>>> y = 1
>>> f = lambda x: x + y
>>> f(1)
2
>>> y = 2
>>> f(1)
3

...所以您只需在调用lambda 之前在调用范围内设置var,尽管这更常用于y 为“常量”的情况。

对该函数的反汇编显示...

>>> import dis
>>> dis.dis(f)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_GLOBAL              0 (y)
              6 BINARY_ADD
              7 RETURN_VALUE

如果您想在定义lambda 时将y 绑定到一个对象(即创建一个closure),通常会看到这个习语...

>>> y = 1
>>> f = lambda x, y=y: x + y
>>> f(1)
2
>>> y = 2
>>> f(1)
2

...在定义lambda 后更改为y 无效。

对该函数的反汇编显示...

>>> import dis
>>> dis.dis(f)
  1           0 LOAD_FAST                0 (x)
              3 LOAD_FAST                1 (y)
              6 BINARY_ADD
              7 RETURN_VALUE

【讨论】:

  • 虽然这很漂亮,而且 OP 要求的是什么,但我为不得不维持这个的可怜的 shmuck 感到抱歉。 “y 到底是从哪里来的?!”在此示例中可能很明显,但在更大的项目中则不然。记住 python 成语“显式优于隐式”......我不认为这是显式的。
  • @JonathonReinhart 我同意。我主要发布这个是因为其他答案暗示这是不可能的,所以我只是想证明它是可能的。这是否是一个好主意是主观的。对于 OP 想要实现的目标,可能有更好的解决方案,但最初的问题并没有真正包含足够的信息来做出决定。
【解决方案2】:

f = functools.partial(lambda var, x: x + var.x - var.y, var) 将为您提供一个参数 (x) 的函数 (f),其中 var 固定为定义时的值。

【讨论】:

    【解决方案3】:

    您不能在 lambda 表达式中使用赋值语句,因此您必须使用常规命名函数:

    def f(x):
        global var
        var = x
    

    注意“global”关键字的使用。没有它,Python 会假设你想在函数的本地范围内创建一个新的“var”变量。

    【讨论】:

    • Upps。抱歉,假设您想分配给变量,而不是对象字段。在这种情况下不需要“全局”(因为您没有引入新的绑定)。
    • 我不认为使用全局变量来“将变量分配到”函数的范围。这是一个全局范围的变量。
    • 我不确定这对我的情况有何帮助?
    • @JonasKlemming 如果变量在全局范围内,则在外部更改它会在任何地方更改它,包括函数内部。这是一个坏主意,但它会起作用。
    • 啊,好吧,也许使用全局毕竟是一个解决方案。
    【解决方案4】:

    让它成为另一个参数:

    f = lambda x,var: x + var.x - var.y
    result = f(10, var)
    

    Lambda 或常规函数,在函数范围内更改变量的唯一方法是通过参数。

    【讨论】:

    • 谢谢,这是我的第一个想法,但我想避免第二次争论。
    • 那么你还能怎么做呢?您如何控制每次调用fvar 是什么?
    • 在这种情况下是的,在每个你想使用它的地方重新定义 lambda。看起来很傻很复杂。 (也就是难以理解、维护等)
    • 为什么避免第二个参数?如果你想要两条数据,为什么要隐藏它?
    • 好吧,但是不使用的时候,那var是什么?这变得如此复杂。或许您需要提供更多信息/代码来帮助我们了解究竟您想要做什么。我会考虑删除整个问题并重新开始。
    猜你喜欢
    • 1970-01-01
    • 2018-08-09
    • 1970-01-01
    • 2014-07-14
    • 1970-01-01
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多