What does the lambda self: do
这个答案解释了如何动态创建测试用例。
答案的代码:
1 2 3 4 5 6 7 8 9 | class Tests(unittest.TestCase): def check(self, i, j): self.assertNotEquals(0, i-j) for i in xrange(1, 4): for j in xrange(2, 6): def ch(i, j): return lambda self: self.check(i, j) setattr(Tests,"test_%r_%r" % (i, j), ch(i, j)) |
我已经测试过它的确有效,但我不知道怎么做?
我无法理解这里的
首先:从函数返回lambda,以防止稍后使用
与以下内容比较:
1 2 3 | for i in xrange(1, 4): for j in xrange(2, 6): setattr(Tests,"test_%r_%r" % (i, j), lambda self: self.check(i, j)) |
这将无法按预期工作,因为所有lambda将共享相同的命名空间,并将在循环结束后使用
我们可以通过将
1 2 3 4 5 6 | from itertools import product from operator import methodcaller for i, j in product(range(1, 4), range(2, 6)): setattr(Tests,"test_%r_%r" % (i, j), lambda self, i=i, j=j: self.check(i, j)) |
Is the lambda used here to perform the exact opposite of functools.partial() (i.e. to create a wrapper function with one extra parameter that is not yet known)
并不是的。它只是在作为参数给出的任何内容上调用
Is self a meaningful keyword or would lambda spam would work just as well?
What point is that lambda evaluated?
只要在
How come the .check() is perfectly fine outside the classes scope?
因为它在lambda中只会稍后使用
相当于
1 2 | def a_function(x): return do_something_with(x) |
在您的特定示例中,创建的函数是实例方法。因此,例如你可以写:
1 2 3 | class Tests: ... test_1_2 = lambda self: self.check(1, 2) |
这相当于:
1 2 3 4 | class Tests: ... def test_1_2(self): return self.check(1, 2) |
现在,由于标识符是动态生成的,因此使用
Is the lambda used here to perform the exact opposite of functools.partial() (i.e. to create a wrapper function with one extra
parameter that is not yet known)
不,不是真的。实际上
1 | test_1_2 = lambda self: self.check(1, 2) |
会成为
1 | test_1_2 = partial(Tests.check, i=1, j=2) |
Is self a meaningful keyword or would lambda spam would work just as well?
Instance方法的第一个参数总是需要是实例。约定是将参数命名为
What point is that lambda evaluated?
How come the .check() is perfectly fine outside the classes scope?
事实并非如此。它是
lambda返回一个函数。
因此,ch(i,j)是i和j的函数,它返回self的函数。
self在Python中没有任何神奇的含义 - 除了一些内置函数之外,每个变量和函数都是显式的。但是只要这些方法附在课堂上,自我就成了他们的第一个论点。
这意味着
-
循环之后The Tests类获取多个名为check_i_j的方法
-
它们中的每一个都包含值i和j
-
他们每个都有第一个名为
self 的参数,这是很好的因为它们是在类中定义的,它们是实例方法,因此它们的第一个参数应该按照约定被称为self