当前位置: 首页 > 面试题库 >

Python Lambda和变量绑定

符畅
2023-03-14
问题内容

我一直在研究用于自动构建的基本测试框架。下面的代码代表使用不同程序对两台机器之间的通信进行的简单测试。在实际执行任何测试之前,我想完全定义它们-
因此,下面的此测试直到声明所有测试后才真正运行。这段代码只是测试的声明。

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变量是在外部范围中定义的,因此,在lambda运行该变量时,它将始终设置为列表中的最后一个客户端。

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

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

由于默认值是在定义lambda时评估的,因此其值将保持正确。

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

def createLambda(client):
    return lambda: client.returncode(CMD2) == 0
#...
passIf = createLambda(client)

这里拉姆达指client在可变createLambda的功能,其具有正确的值。



 类似资料:
  • 变量绑定默认是不可变的,但加上 mut 修饰语后变量就可以改变。 fn main() { let _immutable_binding = 1; let mut mutable_binding = 1; println!("Before mutation: {}", mutable_binding); // 正确代码 mutable_binding += 1

  • Rust 通过静态类型确保类型安全。变量绑定可以在声明变量时标注类型。不过在多数情况下,编译器能够 从字面内容推导出变量的类型,大大减少了标注类型的负担。 使用 let 绑定操作可以将值(像具体数据)绑定到变量中。 fn main() { let an_integer = 1u32; let a_boolean = true; let unit = (); // 将

  • 问题内容: 考虑这样的循环: 输出为: 我希望它是:0、1。我看到两种解决方法: 解决方案#1。 这一事实基于我们可以将数据传递给setTimeout的事实。 解决方案#2。 还有其他选择吗? 问题答案: 除了您提出的两种方法外,没有什么其他的,但这是另一种方法 本质上,您需要捕获闭包中的变量值。此方法使用立即调用的匿名函数将本地变量中的外部变量值捕获。

  • Rust 语言可以先声明变量绑定,后面才将它们初始化。但是这种情况用得很少,因为这样很可能导致使用未 初始的变量。 fn main() { // 声明一个变量绑定 let a_binding; { let x = 2; // 初始化一个绑定 a_binding = x * x; } println!("a bi

  • 事实上每一个非“Hello World” Rust 程序都用了变量绑定。他们将一些值绑定到一个名字上,这样可以在之后使用他们。let被用来声明一个绑定,像这样: fn main() { let x = 5; } 在每个例子中都写上fn main() {有点冗长,所以之后我们将省略它。如果你是一路看过来的,确保你写了main()函数,而不是省略不写。否则,你将得到一个错误。 模式(Patt

  • 变量绑定有一个作用域,并且限定在一个代码块(block)中存活(live)。代码块是一个被 {} 包围的 语句集合。另外也允许变量隐藏。 fn main() { // 此绑定存在于 main 函数中 let long_lived_binding = 1; // 这是一个代码块,比 main 函数拥有一个更小的作用域 { // 此绑定只存在于本代码块