Python 邓德方法中的等式

Python 邓德方法中的等式,python,Python,我想用dunder方法比较两个相同类型的对象,求相等。每个对象都存储“单词”、“发音”、“重量”和“来源”的值,并且在所有内容都相同的情况下达到相等。 我的解决方案看起来像下面这样,但它感觉很笨拙,我确信有更好的方法 def __eq__(self, other): if self.check_other(other): # checks of both objects are snstances of LexicalEntity return_b

我想用dunder方法比较两个相同类型的对象,求相等。每个对象都存储“单词”、“发音”、“重量”和“来源”的值,并且在所有内容都相同的情况下达到相等。 我的解决方案看起来像下面这样,但它感觉很笨拙,我确信有更好的方法

    def __eq__(self, other):
        if self.check_other(other): # checks of both objects are snstances of LexicalEntity
            return_bool = True
            if self.word != other.get_word():
                return_bool = False
            if self.weight != other.get_weight():
                return_bool = False
            if self.source != other.get_source():
                return_bool = False
            if self.pron != other.get_pron():
                return_bool = False
            return return_bool

谢谢你的帮助。

我想这可能更容易理解:

    def __eq__(self, other):
        if self.check_other(other): 
            attrs = ["word", "weight", "source", "pron"]
            return all([getattr(self, attr) == getattr(other, attr) for attr for attrs])

但我想,如果我们想要更具可读性或更智能的解决方案,这是一个首选。对于初学者来说,在Python中不要使用getter和setter。这将使您的代码不那么笨重,更习惯化,也就是说,您不需要
other.get\u word()
,您只需要
other.word
,并且删除
get\u word
的定义,它是无用的。巨蟒!=爪哇

因此,对于这种情况,典型的实现方式是:

def __eq__(self, other):
    if isinstance(other, LexicalEntity):
        these_values = self.word, self.weight, self.source, self.pron
        other_values = other.word, other.weight, other.source, other.pron
        return these_values == other_values
    return NotImplemented # important, you don't want to return None 
        
或者,您也可以只使用一个长布尔表达式:

def __eq__(self, other):
    if isinstance(other, LexicalEntity):
        return (
            self.word == other.word and self.weight == other.weight
            and self.source == other.source and self.pron == other.pron
        )
    return NotImplemented

getter和setter在Python中没有多大意义,如果您确实有重要的验证,那么您应该这样做——如果您只是为了数据封装而这样做的话,Python的原则在这方面要宽松得多,所以不要使用getter/setter

至于断言相等,如果您想避免手动引用每个属性,下面的反射几乎适用于任何情况:

def\uuuuu eq\uuuuu(自身、其他):
如果存在(其他、自身类):
属性=[
如果不是a.startswith(“”)且不可调用(getattr(self,a))的话,则表示in dir(self)中的a
]
返回所有([getattr(self,attr)==getattr(other,attr),用于attr中的attr])
返回未执行

正如@juanpa.arrivillaga已经提到的,返回
NotImplemented
(与引发
NotImplementedError
不同,如下评论所述)很重要,因为如果
other
来自不同的类,这会阻止您在平等检查中返回
None
。关于为什么
return NotImplemented
的更好解释是这些情况下的回退,请参见。

我正要发布相同的答案。。。您可以删除方括号(
[…]
),并将其用作生成器表达式,以避免在内存中创建不必要的列表。您不应该
引发NotImplementedError
。您应该
返回NotImplemented
。用于抽象方法,或者需要实现但尚未完全编写的方法。是二进制特殊方法的特殊返回值,表示它们不支持其他操作数。谢谢@user2357112supportsMonica,我已经更正了答案。如果有人想找到更好的解释,试试看。试过了,效果很好。我最终以不同的方式解决了这个问题,但我真的很喜欢你的第二种方法。它将在未来的任务中派上用场,我肯定会使用它。谢谢