首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python Lambdas和变量绑定

Python Lambdas和变量绑定
EN

Stack Overflow用户
提问于 2010-04-28 23:57:34
回答 2查看 2K关注 0票数 7

我一直在为自动化构建开发一个基本的测试框架。下面的代码片段表示使用不同程序的两台机器之间的通信的简单测试。在我实际做任何测试之前,我想要完整地定义它们-所以下面的测试直到所有测试都被声明之后才会实际运行。这段代码只是一个测试声明。

代码语言:javascript
复制
remoteTests = []
for client in clients:
    t = Test(
        name = 'Test ' + str(host) + ' => ' + str(client),
        cmds = [
            host.start(CMD1),
            client.start(CMD2),

            host.wait(5),

            host.stop(CMD1),
            client.stop(CMD2),
        ],
        passIf = lambda : client.returncode(CMD2) == 0
    )
remoteTests.append(t)

无论如何,在测试运行之后,它会运行由'passIf‘定义的函数。由于我想为多个客户端运行此测试,因此我将迭代它们并为每个客户端定义一个测试--这没什么大不了的。但是,在第一个客户端上运行测试后,“passIf”会对客户端列表中的最后一个客户端求值,而不是在声明lambda时对“client”求值。

那么我的问题是: python什么时候在lambdas中绑定变量引用?我想,如果在lambda之外使用变量是不合法的,解释器就不会知道我在说什么。相反,它会默默地绑定到最后一个“客户端”的实例。

另外,有没有办法强制执行我想要的解决方案?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-04-29 00:03:59

client变量是在外部作用域中定义的,因此在运行lambda时,它将始终被设置为列表中的最后一个客户端。

要获得预期的结果,您可以为lambda提供一个带有默认值的参数:

代码语言:javascript
复制
passIf = lambda client=client: client.returncode(CMD2) == 0

由于默认值是在定义lambda时计算的,因此它的值将保持正确。

另一种方法是在函数中创建lambda:

代码语言:javascript
复制
def createLambda(client):
    return lambda: client.returncode(CMD2) == 0
#...
passIf = createLambda(client)

这里的lambda引用createLambda函数中的client变量,该变量具有正确的值。

票数 10
EN

Stack Overflow用户

发布于 2010-04-29 00:05:55

发生的情况是,您的passIf参数lambda引用了封闭作用域中的变量client。它不是指变量client在创建时引用的对象,而是指变量本身。如果在循环结束后调用这些passIf,这意味着它们都引用循环中的最后一个值。(在闭包术语中,Python的闭包是后期绑定的,而不是早期绑定的。)

幸运的是,将后期绑定闭包转换为早期绑定闭包相当容易。你可以简单的给lambda一个参数,默认的是你想要绑定的值:

代码语言:javascript
复制
passIf = lambda client=client: client.returncode(CMD2) == 0

这确实意味着函数获得了额外的参数,如果意外地使用参数调用它,或者当您希望函数接受任意参数时,可能会把事情搞得一团糟。所以另一种技术是这样做的:

代码语言:javascript
复制
# Before your loop:
def make_passIf(client):
    return lambda: client.returncode(CMD2) == 0

# In the loop
t = Test(
    ...
    passIf = make_passIf(client)
)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2731111

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档