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))
我已经测试过了,而且很管用,但我不能只知道如何?
我很难理解这里的魔术,主要是:
functools.partial()
完全相反的操作(即使用一个未知的extra参数创建包装函数)self
一个有意义的关键字,还是lambda spam
也同样有效?.check()
在class
es作用域之外是完美的?
lambda返回一个函数。
self
是它的参数,i和j在它的内部因此,ch(i,j)是i和j的函数,它返回的函数。
self在这里没有任何神奇的含义,因为在Python中没有任何东西——除了一些内置的变量和函数之外,每个变量和函数都是显式的。但一旦这些方法附加到类,self就成为它们的第一个参数。
这意味着
循环之后,Tests类将获得多个名为check_i_j的方法
它们中的每一个都有值i和j包含在其中
它们中的每一个都有其名为
self
的第一个参数,这很好,因为它们是在类内定义的,它们是实例方法,因此它们的第一个参数应该按照约定称为selfa_function = lambda x: do_something_with(x)
相当于
在您的特定示例中,创建的函数是实例方法。例如,您可以编写:
相当于:
现在,由于标识符是动态生成的,因此使用
setattr
。不,不是真的。实际上
partial
也可以在这里使用。会变成
实例方法的第一个参数始终需要是实例。约定是命名参数
self
,但您可以使用任何其他名称。我不建议这样做,因为这会使你的代码更难阅读和理解。lambda
创建匿名函数,任何函数都是在调用时求值的。不是。它是
self.check()
,其中self
是Tests
类的实例。首先:lambda是从函数返回的,以防止以后使用
i
和j
的修改值。与以下内容进行比较:
这将无法按预期工作,因为所有lambda将共享同一命名空间,并在循环结束后使用
i
和j
的值。如果使用单独的函数调用,则每次都会引入一个新的闭包,该闭包在调用函数的时间点捕获i
和j
的值。我们可以通过将当前值
i
和j
保存为lambda的默认参数来实现相同的目的。为了获得更好的度量,我们还使用itertools.product
来避免嵌套循环:不是真的。它只调用作为参数给定的
check(i, j)
方法。这里使用它动态地向Tests
类添加方法。spam
也同样有效。他们在这里选择self
是由于约定,因为lambda表示一个方法。只要对
Tests
的实例调用test_[i]_[j]()
。因为它在lambda中,稍后只会使用
Tests
的实例作为self
参数调用它。相关问题 更多 >
编程相关推荐