兰达自己是什么:d

2024-03-29 12:35:33 发布

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

This answer解释如何动态创建测试用例。

答案代码:

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))

我已经测试过了,而且很管用,但我不能只知道如何

我很难理解这里的魔术,主要是:

  1. lambda是否用于执行与functools.partial()完全相反的操作(即使用一个未知的extra参数创建包装函数)
  2. self一个有意义的关键字,还是lambda spam也同样有效?
  3. 兰姆达的评价是什么?
  4. 为什么.check()classes作用域之外是完美的?
  5. 如果没有lambda,你怎么做?-如果我理解正确,you should be able to do without ^{}(更不用说我同意Guido和Alex的观点,即它是一个眼中钉,我想让eem不用:)

Tags: lambda答案代码answerinselffordef
3条回答

lambda返回一个函数。self是它的参数,i和j在它的内部

因此,ch(i,j)是i和j的函数,它返回函数。

self在这里没有任何神奇的含义,因为在Python中没有任何东西——除了一些内置的变量和函数之外,每个变量和函数都是显式的。但一旦这些方法附加到类,self就成为它们的第一个参数。

这意味着

  • 循环之后,Tests类将获得多个名为check_i_j的方法

  • 它们中的每一个都有值i和j包含在其中

  • 它们中的每一个都有其名为self的第一个参数,这很好,因为它们是在类内定义的,它们是实例方法,因此它们的第一个参数应该按照约定称为self

a_function = lambda x: do_something_with(x)

相当于

def a_function(x):
    return do_something_with(x)

在您的特定示例中,创建的函数是实例方法。例如,您可以编写:

class Tests:
...
   test_1_2 = lambda self: self.check(1, 2)

相当于:

class Tests:
...
   def test_1_2(self):
       return self.check(1, 2)

现在,由于标识符是动态生成的,因此使用setattr


  1. 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)

不,不是真的。实际上partial也可以在这里使用。

test_1_2 = lambda self: self.check(1, 2)

会变成

test_1_2 = partial(Tests.check, i=1, j=2)
  1. Is self a meaningful keyword or would lambda spam would work just as well?

实例方法的第一个参数始终需要是实例。约定是命名参数self,但您可以使用任何其他名称。我不建议这样做,因为这会使你的代码更难阅读和理解。

  1. What point is that lambda evaluated?

lambda创建匿名函数,任何函数都是在调用时求值的。

  1. How come the .check() is perfectly fine outside the classes scope?

不是。它是self.check(),其中selfTests类的实例。

首先:lambda是从函数返回的,以防止以后使用ij的修改值。

与以下内容进行比较:

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将共享同一命名空间,并在循环结束后使用ij的值。如果使用单独的函数调用,则每次都会引入一个新的闭包,该闭包在调用函数的时间点捕获ij的值。

我们可以通过将当前值ij保存为lambda的默认参数来实现相同的目的。为了获得更好的度量,我们还使用itertools.product来避免嵌套循环:

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)

不是真的。它只调用作为参数给定的check(i, j)方法。这里使用它动态地向Tests类添加方法。

Is self a meaningful keyword or would lambda spam would work just as well?

spam也同样有效。他们在这里选择self是由于约定,因为lambda表示一个方法。

What point is that lambda evaluated?

只要对Tests的实例调用test_[i]_[j]()

How come the .check() is perfectly fine outside the classes scope?

因为它在lambda中,稍后只会使用Tests的实例作为self参数调用它。

相关问题 更多 >