2017-04-23 15 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 

比較がFalseを返す場合assertAssertionErrorをスローします使用します。

0

アブソリュート条件がfalseの場合、Robert Seamanはassert raiseをAssertionErrorとしています。エラーが発生すると、エラーメッセージが表示され、プログラムが終了します。あなたはおそらくをしないでくださいが起こることを願っています。 ;)代わりに、以下に示すように、タイプチェックをotherにする必要があります。

assertステートメントは、ではなく、でデータの有効性をテストする必要があります。アサーションは、プログラムのロジックの欠陥を捕まえることを目的としています。assertテストが失敗した場合、プログラムのロジックが間違っていて、修正する必要があると思われる場合。

よりもむしろtype機能付きタイプのテストをやって、それがisinstanceを使用することをお勧めします、例えば

if isinstance(other, Student): 

それはまた、より柔軟です:otherがテストに合格しますStudentから派生したクラスである場合。

は、

代わり
if some_condition: 
    return True 
else: 
    return False 

を行い、このはるかにコンパクト版は使用しないでください:some_conditionが実際にブール(FalseまたはTrue)されていない場合

return some_condition. 

をし、実際に必要あなたが行うかもしれないブール値を返す関数

return bool(some_condition) 

これをブール値に変換するには、一般的には必要ありません。

から継承するようにクラスを定義する必要があります。そうしないと、新しいスタイルの新しいクラスではなく古いスタイルのクラスが作成されます(Python 3ではすべてのクラスが新しい-styleなので、objectから明示的に継承する必要はありません)。

改善の余地がありますStudent.__repr__メソッドです。Studentインスタンス属性(lastnamefirstname、およびfavcolor)はすべて文字列なので、strを呼び出す必要はありません。 +を使用して文字列を連結しますが、.formatまたは.joinの方法を使用する方が便利なことがよくあります。また、__repr__はプログラマが使用するためのもので、理想的にはオブジェクトを再構成するために使用できる文字列を返す必要があります。ユーザーフレンドリーな文字列を作成するには__str__を使用してください。 (クラスが__repr__を定義していて、__str__を定義していない場合は、オブジェクトに対してstrを呼び出すときに__repr__が使用されます)。

ここではPython 2とPythonの両方で実行されますあなたのStudentクラスの改良版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