首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >dunder中的等式

dunder中的等式
EN

Stack Overflow用户
提问于 2020-08-26 10:04:49
回答 3查看 349关注 0票数 3

我想将两个相同类型的对象与dunder方法__eq__进行比较,以获得相等的结果。每个对象存储“单词”、“发音”、“权重”和“源”的值,当一切相同时,达到相等。我的解决方案如下所示,但感觉很笨重,而且我相信还有更好的方法。

代码语言:javascript
复制
    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

谢谢你的帮助。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-26 10:32:36

首先,不要使用Python中的getter和setter。这将使您的代码更少笨重和更地道,也就是说,您不需要other.get_word(),您只需要other.word,并删除您对get_word的定义,这是无用的。Python != Java。

所以,对于这样的东西,一个典型的实现是:

代码语言:javascript
复制
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 

或者,您也可以使用一个长的布尔表达式:

代码语言:javascript
复制
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
票数 2
EN

Stack Overflow用户

发布于 2020-08-26 10:13:28

我认为这可能有点可读性:

代码语言:javascript
复制
    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])

但我想如果我们想要更易读或更聪明的解决方案,这是一种偏好

票数 1
EN

Stack Overflow用户

发布于 2020-08-26 11:38:28

Getters和setter在Python中没有多大意义,您应该使用start using the @property annotation instead,如果您确实有重要的验证--如果您只是为了数据封装而这样做,Python原则在这方面要松散得多,所以只需抛弃getters/setter。

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

代码语言:javascript
复制
def __eq__(self, other):
    if isinstance(other, self.__class__):
        attrs = [
            a for a in dir(self) if not a.startswith('_') and not callable(getattr(self, a))
        ]
        return all([getattr(self, attr) == getattr(other, attr) for attr in attrs])
    
    return NotImplemented

正如@juanpa.arrivillaga已经提到的,返回NotImplemented (与引发NotImplementedError不一样,在下面的注释中已经注意到)很重要,因为如果other来自不同的类,这将阻止您在等式检查中返回None。更好地解释为什么return NotImplemented是在这些情况下的退路是在this answer中找到的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63595261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档