平等覆盖问题
Equality override issue
我是 Python 的新手,我很困惑为什么会收到覆盖错误。我正在尝试构建一个 class 网络并将其表示为由 BST 表示的字典。字典中的键可以是值为课程列表的 Student 对象,也可以是值为学生列表的课程(字符串)。问题是,在分析课程是否在字典中时,尽管它是一个字符串对象,它仍然使用 Student class 的相等性。
你应该 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
如果比较 return False
.
,则使用 assert
将抛出 AssertionError
正如 Robert Seaman 所提到的,如果断言条件为假,assert
会引发 AssertionError
。发生这种情况时,将打印一条错误消息并终止您的程序。您可能不希望这种情况发生。 ;) 相反,您应该将 other
的类型检查作为相等性测试中的第一项,如下所示。
assert
语句应该不用于测试数据的有效性。断言旨在捕捉程序逻辑中的缺陷:如果 assert
测试失败,这应该表明您的程序逻辑错误,您需要修复它。
与其使用type
函数进行类型测试,不如使用isinstance
,例如
if isinstance(other, Student):
它也更灵活:如果 other
是从 Student
派生的 class,则测试将通过。
不要
if some_condition:
return True
else:
return False
相反,使用这个更紧凑的版本:
return some_condition.
如果 some_condition
实际上不是布尔值(False
或 True
)并且您实际上 需要 [=87 的函数=] 你可以做的布尔值
return bool(some_condition)
将其转换为布尔值,但这通常不是必需的。
此外,您似乎仍在使用 Python 2. 您应该将 class 定义为从 object
继承,否则您将获得旧式 classes 而不是高级新式 classes(在 Python 3 中所有 classes 都是新式的,所以你不需要显式地继承自 object
).
您的 Student.__repr__
方法还有改进的余地。似乎所有 Student
实例属性(lastname
、firstname
和 favcolor
)都是字符串,因此无需对它们调用 str
。您 可以 使用 +
连接字符串,但通常使用 .format
或 .join
方法更方便。此外,__repr__
是供程序员使用的,理想情况下它应该是 return 一个可用于重新构造对象的字符串;使用 __str__
创建用户友好的字符串。 (如果 class 定义了 __repr__
但没有定义 __str__
那么当你在对象上调用 str
时使用 __repr__
。
这是您的 Student
class 的改进版本,可在 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
我是 Python 的新手,我很困惑为什么会收到覆盖错误。我正在尝试构建一个 class 网络并将其表示为由 BST 表示的字典。字典中的键可以是值为课程列表的 Student 对象,也可以是值为学生列表的课程(字符串)。问题是,在分析课程是否在字典中时,尽管它是一个字符串对象,它仍然使用 Student class 的相等性。
你应该 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
如果比较 return False
.
assert
将抛出 AssertionError
正如 Robert Seaman 所提到的,如果断言条件为假,assert
会引发 AssertionError
。发生这种情况时,将打印一条错误消息并终止您的程序。您可能不希望这种情况发生。 ;) 相反,您应该将 other
的类型检查作为相等性测试中的第一项,如下所示。
assert
语句应该不用于测试数据的有效性。断言旨在捕捉程序逻辑中的缺陷:如果 assert
测试失败,这应该表明您的程序逻辑错误,您需要修复它。
与其使用type
函数进行类型测试,不如使用isinstance
,例如
if isinstance(other, Student):
它也更灵活:如果 other
是从 Student
派生的 class,则测试将通过。
不要
if some_condition:
return True
else:
return False
相反,使用这个更紧凑的版本:
return some_condition.
如果 some_condition
实际上不是布尔值(False
或 True
)并且您实际上 需要 [=87 的函数=] 你可以做的布尔值
return bool(some_condition)
将其转换为布尔值,但这通常不是必需的。
此外,您似乎仍在使用 Python 2. 您应该将 class 定义为从 object
继承,否则您将获得旧式 classes 而不是高级新式 classes(在 Python 3 中所有 classes 都是新式的,所以你不需要显式地继承自 object
).
您的 Student.__repr__
方法还有改进的余地。似乎所有 Student
实例属性(lastname
、firstname
和 favcolor
)都是字符串,因此无需对它们调用 str
。您 可以 使用 +
连接字符串,但通常使用 .format
或 .join
方法更方便。此外,__repr__
是供程序员使用的,理想情况下它应该是 return 一个可用于重新构造对象的字符串;使用 __str__
创建用户友好的字符串。 (如果 class 定义了 __repr__
但没有定义 __str__
那么当你在对象上调用 str
时使用 __repr__
。
这是您的 Student
class 的改进版本,可在 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