2012-02-16 60 views
2

是否可以使用assert_equal來比較對象?我不斷看到這樣的錯誤:學習Python的難題,例49:使用assert_equal來比較對象

AssertionError: <ex49.parser.Sentence object at 0x01F1BAF0> != 
<ex49.parser.Sentence object at 0x01F1BB10> 

相關的代碼片段:

def test_parse_subject(): 

    testsentence = "princess go east" 
    result = lexicon.scan(testsentence) 
    Sent = parse_sentence(result) 
    ResultSent = Sentence(('subject', 'princess'), 
         ('verb', 'go'), 
         ('object', 'east')) 
    print ResultSent.subject 
    print ResultSent.verb 
    print ResultSent.object 
    print Sent.subject 
    print Sent.verb 
    print Sent.object 
    assert_equal(Sent, ResultSent) 

屏幕上的打印輸出表明對象具有相同的內容 - 但斷言錯誤出現。爲什麼是這樣?有什麼方法可以用assert_equal來覆蓋這個嗎?

回答

6

我相信你需要在Sentence類上實現__eq__方法。

assertEqual(first, second, msg=None)¶ Test that first and second are equal. If the values do not compare equal, the test will fail.

In addition, if first and second are the exact same type and one of list, tuple, dict, set, frozenset or unicode or any type that a subclass registers with addTypeEqualityFunc() the type-specific equality function will be called in order to generate a more useful default error message (see also the list of type-specific methods).

Python unittest documentation

The correspondence between operator symbols and method names is as follows: xlt(y), x<=y calls x.le(y), x==y calls x.eq(y), x!=y and x<>y call x.ne(y), x>y calls x.gt(y), and x>=y calls x.ge(y).

Python data model documentation

一個例子:

import unittest 


class A: 

    def __init__(self, num): 
     self.num = num 

    def __eq__(self, other): 
     return self.num == other.num 


class Test(unittest.TestCase): 

    def test(self): 
     a1 = A(1) 
     a12 = A(1) 
     a2 = A(2) 

     self.assertEqual(a1, a1, 'a1 != a1') 
     self.assertEqual(a1, a12, 'a1 != a12') 
     self.assertEqual(a1, a2, 'a1 != a2') 

def main(): 
    unittest.TestRunner(Test()) 

if __name__ == '__main__': 
    unittest.main() 

現在發表意見__eq__方法,看到了差距。

0

我也在通過LPTHW ex49工作。特別是在這個例子的情況下,我能得到它通過添加__eq __()方法,來了句類工作,具體如下:

Class Sentence(object): 

    def __init__(self, subject, verb, object_) 
     ... 

    def __eq__(self, other): 
     return (self.subject == other.subject and 
       self.verb == other.verb and 
       self.object_ == other.object_) 

然後,在測試文件,我所做的:

# where LIST5 is defined above to give list of two tuples, [('verb', 'go'), ('direction', 'east')] 
def test_parse_subject(): 
    wordlist = list(LIST5) 
    sent = parse.Sentence(('noun', 'person'), ('verb'), ('go'), ('direction', 'east)) 
    newsent = parse.parse_subject(wordlist, ('noun', 'person')) 
    assert_equal(newsent, sent) 

據我所知(新來這個),assert_equal與鼻子和unittest將調用__eq __()方法,如果它存在。在這種情況下,只要兩個對象的主體,動詞,object_具有相同的三個值,測試就可以。但是,這花了我一段時間才弄清楚,因爲我的代碼中存在一個錯誤,並且鼻子提供的唯一一件事情就是您收到的錯誤消息,即使我有__eq __()方法。也就是說,它提供了「AssertionError:...對象在0x ...!= ...對象在0x ...」這使我誤以爲__eq __()方法不起作用,因爲它看起來像是比較地址。不知道是否有更好的方法來做到這一點。

注意:我將對象重命名爲object_,因爲gedit突出顯示了對象作爲python關鍵字。不確定是否建議使用尾部下劃線。

1

這是好消息,對我來說,我是懶得搜索的兩個對象,所以我只是比較的變量如下:

def test_parse_subject(): 
    word_list_a = lexicon.scan("eat the bear") 
    Sentence1 = Sentence(('noun','player'),('verb', 'eat'),('noun', 'bear')) 
    Sentence2 = parse_subject(word_list_a,('noun','player')) 

    assert_equal(Sentence2.subject, Sentence1.subject) 
    assert_equal(Sentence2.verb, Sentence1.verb) 
    assert_equal(Sentence2.object, Sentence1.object)