2017-04-23 75 views
1

我是新来的Python,我很困惑,为什么我得到一个覆盖错误。我正在尝试构建一个类网络,并将其表示为由BST代表的字典。字典中的键可以是具有值列表的课程对象的Student对象,也可以是具有值列表的学生的课程(字符串)。问题是,当分析课程是否在字典中时,它尽管是一个字符串对象,仍然使用Student类的平等。这里是我的代码:平等覆盖问题

def getClassList(): 
ClassList = []  # an empty list to be filled from class.csv file 
with open('lab6.csv', 'rb') as f: # access local file 'class.csv' 
    reader = csv.reader(f)   # connects reader object to file 
    for row in reader:    # reads one text line at a time 
     ClassList += [row]   # .. and appends to the ClassList 
return ClassList 

class Student: 
    def __init__(self, lastname, firstname, favcolor): 
    # assert(True) 
    self.lastname = lastname 
    self.firstname = firstname 
    self.favcolor = favcolor 

    def __eq__(self, other): 
    assert(type(other) == type(self)) 
    if (self.lastname == other.lastname and self.firstname == other.firstname and self.favcolor == other.favcolor): 
     return True 
    else: 
     return False 

def __repr__(self): 
    return str(self.firstname)+' '+str(self.lastname) 

class ClassNetwork: 
def __init__(self): 
    #creating an empty graph 
    self.rep=Dictionary() 
    #using the getClassList function to get the necessary info to create the graph 
    classlist=getClassList() 
    #not using the first list since it doesn't contain info 
    classlist=classlist[1:] 

    #traversing the list of lists 
    for i in range(len(classlist)): 
     #constructing a new student from each list (Student object) 
     newStudent=Student(classlist[i][0],classlist[i][1],classlist[i][3]) 
     #getting a course from each list (str type) 
     newCourse=str(classlist[i][2]) 

     #HANDLING THE COURSE 
     #checking if the course exists or not 
     if self.rep.lookup(newCourse)=='No entry': 
      #if not, add it 
      self.rep.put(newCourse,[newStudent]) 
     #if course already exists, update the student list 
     else: 
      upCo=self.rep.lookup(newCourse)+[newStudent] 
      self.rep.put(newCourse,upCo) 

     #HANDLING THE STUDENT 
     #checking if the student exists or not 
     if self.rep.lookup(newStudent)=='No entry': 
      #if not, add them - use put method 
      self.rep.put(newStudent,[newCourse]) 
     #if the student already exists, update course list 
     else: 
      #updated value=old courses+the new course 
      upSt=self.rep.lookup(newStudent)+[newCourse] 
      self.rep.put(newStudent,upSt) 

def __repr__(self): 
    return repr(self.rep.rep.inorderlist()) 

错误:

Exception raised: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/doctest.py", line 1315, in __run 
    compileflags, 1) in test.globs 
    File "<doctest __main__[0]>", line 1, in <module> 
    CN = ClassNetwork() 
    File "/homes/user/cs106/Lab 6/lab6.py", line 93, in __init__ 
    if self.rep.lookup(newStudent)=='No entry': 
    File "/homes/user/cs106/Lab 6/lab6.py", line 181, in lookup 
    return self.rep.lookup(key) 
    File "/homes/user/cs106/Lab 6/BST.py", line 81, in lookup 
    elif self.root()[0] == key: 
    File "/homes/user/cs106/Lab 6/lab6.py", line 56, in __eq__ 
    assert(type(other) == type(self)) 
AssertionError 
+0

你最想如果到'返回FALSE'了'学生'不匹配一个字符串。目前,您只使用'assert',因此当比较返回False时为什么会引发'AssertionError'。 –

+1

谢谢你的帮助!它解决了我的问题。 – Silvia

+1

我在下面重复了我的回答 - 如果您可以将此标记为接受的答案,那将非常棒。谢谢。 –

回答

0

你应该return False而不是使用assert

def __eq__(self, other): 
    if type(other) != type(self): 
     return False 
    if (self.lastname == other.lastname and self.firstname == other.firstname and self.favcolor == other.favcolor): 
     return True 
    else: 
     return False 

使用assert将抛出AssertionError如果比较返回False

0

正如罗伯特希曼提到的assert如果声明的条件为假,则会产生AssertionError。发生这种情况时,将打印一条错误消息,并终止您的程序。你可能不要想要发生。 ;)相反,您应该在的类型检查中作为您的平等测试中的第一项,如下所示。

assert声明应该而不是用于测试数据的有效性。断言旨在捕获程序逻辑中的缺陷:如果assert测试失败,这应该表明您的程序的逻辑错误,并且您需要修复它。

,而不是做型式试验与type功能,最好使用isinstance,如

if isinstance(other, Student): 

它也更灵活:如果other是这是一个从Student得出的测试将传递一个类。

不要做

if some_condition: 
    return True 
else: 
    return False 

相反,使用这种更紧凑的版本:

return some_condition. 

如果some_condition实际上不是一个布尔(FalseTrue),你实际需要函数返回一个布尔值,你可能做

return bool(some_condition) 

将其转换为布尔值,但这通常不是必需的。

另外,看起来你还在使用Python 2.你应该定义你的类继承自object,否则你会得到旧式的类而不是优秀的新式类(在Python 3中,所有的类都是新的风格,所以你不需要明确从object继承)。

方法有改进的余地Student.__repr__方法。看起来,所有Student实例属性(lastname,firstnamefavcolor)都是字符串,因此无需在其上调用str。你可以连接字符串使用+,但它通常更方便使用.format.join方法。另外,__repr__是供程序员使用的,理想情况下它应该返回一个可以用来重新构造对象的字符串;使用__str__来创建一个用户友好的字符串。 (如果某个类定义了__repr__但未定义__str__,则当您在该对象上调用str时将使用__repr__)。

这是你的Student类的改进版本,可运行于Python 2和Python 3的

from __future__ import print_function 

class Student(object): 
    def __init__(self, lastname, firstname, favcolor): 
     self.lastname = lastname 
     self.firstname = firstname 
     self.favcolor = favcolor 

    def __eq__(self, other): 
     return (isinstance(other, Student) and self.lastname == other.lastname 
      and self.firstname == other.firstname and self.favcolor == other.favcolor) 

    def __repr__(self): 
     return 'Student({!r}, {!r}, {!r})'.format(self.lastname, self.firstname, self.favcolor) 

    def __str__(self): 
     return '{} {}'.format(self.firstname, self.lastname) 

# test 

students = [ 
    Student('Smith', 'John', 'red'), 
    Student('Jones', 'Fred', 'blue'), 
    'not a student', 
] 

for s1 in students: 
    print(s1) 
    for s2 in students: 
     print(' {!r} : {}'.format(s2, s1 == s2)) 

输出

John Smith 
    Student('Smith', 'John', 'red') : True 
    Student('Jones', 'Fred', 'blue') : False 
    'not a student' : False 
Fred Jones 
    Student('Smith', 'John', 'red') : False 
    Student('Jones', 'Fred', 'blue') : True 
    'not a student' : False 
not a student 
    Student('Smith', 'John', 'red') : False 
    Student('Jones', 'Fred', 'blue') : False 
    'not a student' : True