У меня есть 2 функции, apply_rule
и match
. Каждый из них определяется независимо - они не принадлежат ни к одному классу.Испытание загрязнения в unittest
match
принимает два обязательных параметра и необязательный параметр, называемый pairs
. По умолчанию используется пустой словарь. Ниже приведен код для apply_rule
и для match
. Обратите внимание, что вызывается match
, а необязательный параметр pairs
не указан.
def apply_rule(pat, rule):
if not isrule(rule):
return "Not a valid rule"
subs = match(lhs(rule), pat)
if subs == {}:
return pat
else:
return substitute(rhs(rule), subs)
def match(pat, lst, pairs={}):
if pat == [] and lst == []:
return pairs
elif isvariable(pat[0]):
if pat[0] not in pairs.keys():
pairs[pat[0]] = lst[0]
elif pat[0] in pairs.keys() and lst[0] != pairs[pat[0]]:
return False
elif pat[0] != lst[0]:
return False
return match(pat[1:], lst[1:], pairs)
Прямо сейчас, UnitTest для match
терпит неудачу, потому что он "вспоминает" pairs
, определенной в тесте на apply_rule
.
Однако, если я изменю 3-ю строку в apply_rule
на subs = match(lhs(rule), pat, {})
, тогда тесты пройдут. Знаете ли вы, почему? Насколько я могу судить, не должно быть никакого способа, чтобы match
запоминал значение pairs
с того момента, когда оно было вызвано в других тестах.
Ниже приведены единичные испытания для справки.
def test_match(self):
self.assertEqual({}, match(['a', 'b', 'c'], ['a', 'b', 'c']))
self.assertEqual(self.dict_with_x, match(['a', '_X', 'c'], ['a', '5', 'c']))
self.assertEqual(self.dict_with_x, match(self.pat_with_xx, self.list_with_55))
self.assertEqual(self.dict_with_xy, match(self.pat_with_xy, self.list_with_5hi))
self.assertFalse(match(self.pat_with_xx, ['a', 'b', 'c', 'd']))
self.assertFalse(match(['a', 'b', 'c'], ['a', 'b', 'd']))
def test_apply_and_firerule(self):
pattern1 = "my mother thinks I am fat".split(' ')
expected = "do you think you are fat ?".split(' ')
self.assertEqual(apply_rule(pattern1, self.r1), expected)
И сообщение об ошибке ...
Traceback (most recent call last):
File "pattern_matcher_tests.py", line 65, in test_match
self.assertEqual({}, match(['a', 'b', 'c'], ['a', 'b', 'c']))
AssertionError: {} != {'_Y': 'fat', '_X': 'mother'}
- {}
+ {'_X': 'mother', '_Y': 'fat'}
http://stackoverflow.com/questions/1132941/least-astonishment-in-python-the-mutable-default-argument http://effbot.org/zone/default -values.htm – dm03514