平等覆盖问题

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 实际上不是布尔值(FalseTrue)并且您实际上 需要 [=87 的函数=] 你可以做的布尔值

return bool(some_condition) 

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

此外,您似乎仍在使用 Python 2. 您应该将 class 定义为从 object 继承,否则您将获得旧式 classes 而不是高级新式 classes(在 Python 3 中所有 classes 都是新式的,所以你不需要显式地继承自 object).

您的 Student.__repr__ 方法还有改进的余地。似乎所有 Student 实例属性(lastnamefirstnamefavcolor)都是字符串,因此无需对它们调用 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