【发布时间】:2012-05-01 06:58:48
【问题描述】:
我经常发现自己试图稍微滥用 python 允许的一些动态性(我在这里使用的是 python3,但应该不会有太多差异)。
在这种情况下,我想将 unittest.TestCase 中的单个 test_ 方法拆分为在运行时创建的多个方法。
(这是一个关于罗马数字的Kata,但我实际上没有TDD:我后来写了测试)
这是测试:
class TestNumbers(TestCase):
def test_number(self):
for i in range(3000):
self.assertEqual(i, roman_to_int(int_to_roman(i)))
我就是这样写的:
from functools import partial
from types import MethodType
class TestNumbers(TestCase):
pass
def test_number(self, n):
self.assertEqual(n, roman_to_int(int_to_roman(n)))
for i in range(3000):
name = str(i)
test_method = MethodType(partial(test_number, n=i), TestNumbers)
setattr(TestNumbers, "test" + name, test_method)
(或者,我也尝试动态创建许多 TestCase 子类和setattr(globals(), ...) 它们)
我知道:这并没有太多目的,它也可能更慢,等等。但这只是一个 POC,我正在尝试了解如何让它工作
通过使用 MethodType,测试变成了一个绑定方法,但是在里面,assertEqual 显然变成了一个函数,当试图调用它时,它会失败并显示TypeError: assertEqual() takes at least 3 arguments (2 given)
我尝试将 test_number 更改为
def test_number(self, n):
self.assertEqual(self, n, roman_to_int(int_to_roman(n)))
但这只会在隐藏的 TestCase 方法中更深层次地挖掘出同样的问题:TypeError: _getAssertEqualityFunc() takes exactly 3 arguments (2 given)
我在 stackoverflow 上查看了这里并发现了类似的问题(例如 Python: Bind an Unbound Method? ),但没有一个涉及绑定一个在其中调用目标类的其他绑定方法的方法
我也尝试研究元类 (http://docs.python.org/py3k/reference/datamodel.html#customizing-class-creation),但它似乎与我想要做的不匹配
【问题讨论】:
标签: python dynamic methods bind