Python Lambdas和变量绑定

2024-10-08 18:28:37 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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之外的变量是不合法的,解释者就不知道我在说什么。相反,它静默地绑定到最后一个“client”的实例。在

还有,有没有一种方法可以按照我想要的方式强制执行决议?在


Tags: lambda代码testclienthost声明客户机定义
2条回答

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

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

passIf = lambda client=client: client.returncode(CMD2) == 0

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

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

^{pr2}$

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

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

幸运的是,将后期绑定闭包转换为早期绑定闭包相当容易。您只需为lambda提供一个参数,并将要绑定的值作为默认值:

passIf = lambda client=client: client.returncode(CMD2) == 0

这意味着函数得到了额外的参数,如果意外地用一个参数调用它,或者当你希望函数接受任意参数时,它可能会把事情搞砸。所以另一种方法是这样做:

^{pr2}$

相关问题 更多 >

    热门问题