ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

如何比较python中自定义类中None对象的相等性?

2019-08-25 10:59:38  阅读:266  来源: 互联网

标签:python class object equals comparison


我正在为python编写一个Queue数据结构,纯粹是为了学习目的.这是我的课.当我比较两个Queue对象的相等性时,我得到错误.我认为错误会弹出,因为我在__eq__中没有比较None.但是我如何检查None并返回accinly.事实上,我正在使用引擎盖下的列表并调用它的__eq__,认为它应该注意如此处所示,但它没有

>>> l=[1,2,3]
>>> l2=None
>>> l==l2
False

这是我的班级:

@functools.total_ordering
class Queue(Abstractstruc,Iterator):

    def __init__(self,value=[],**kwargs):
        objecttype = kwargs.get("objecttype",object)
        self.container=[]
        self.__klass=objecttype().__class__.__name__
        self.concat(value)


    def add(self, data):
        if (data.__class__.__name__==self.__klass or self.__klass=="object"): 
            self.container.append(data)
        else:
            raise Exception("wrong type being added")

    def __add__(self,other):
        return Queue(self.container + other.container)


    def __iadd__(self,other):
        for i in other.container:
            self.add(i)
        return self


    def  remove(self):
        return self.container.pop(0)


    def peek(self):
        return self.container[0]


    def __getitem__(self,index):
        return self.container[index]


    def __iter__(self):
        return Iterator(self.container)

    def concat(self,value):
        for i in value:
            self.add(i)

    def __bool__(self):
        return len(self.container)>0

    def __len__(self):
        return len(self.container)


    def __deepcopy__(self,memo):
        return Queue(copy.deepcopy(self.container,memo))

    def __lt__(self,other):
        return self.container.__lt__(other.container)

    def __eq__(self, other):
        return self.container.__eq__(other.container)

但是当我尝试使用上面的类进行比较时,我得到:

>>> from queue import Queue
>>> q = Queue([1,2,3])
>>> q
>>> print q
<Queue: [1, 2, 3]>
>>> q1 = None
>>> q==q1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "queue.py", line 65, in __eq__
    return self.container.__eq__(other.container)
AttributeError: 'NoneType' object has no attribute 'container'
>>> 

解决方法:

您的问题是如何实现__eq__.

看看这段代码:

q = Queue([1,2,3])
q1 = None
q==q1

并让我们将其重写为等效:

q = Queue([1,2,3])
q == None

现在,在Queue .__ eq__中,我们有:

def __eq__(self, other):
    return self.container.__eq__(other.container)

但是其他是None,这意味着return语句正在调用:

self.container.__eq__(None.container)

正如您的错误所述:

'NoneType' object has no attribute 'container'

因为它没有! None没有容器属性.

所以,这样做的方式取决于你想如何对待它.现在,显然,如果已定义Queue对象,则它不能为None,因此:

return other is not None and self.container.__eq__(other.container)

懒惰地评估其他是否为None,并在之前将表达式的部分删除之前返回False.否则,它将执行评估.但是,如果其他不是Queue类型(或者更准确地说其他对象没有容器属性),则会出现其他问题,例如:

q = Queue([1,2,3])
q == 1
>>> AttributeError: 'int' object has no attribute 'container'

所以…取决于你的逻辑,如果一个队列不能与其他类型“相等”(这是你可以说的话),你可以检查正确的类型,如下所示:

return other is not None and type(self) == type(other) and self.container.__eq__(other.container)

但是…… None是NoneType,因此它永远不会与Queue的类型相同.所以我们可以再简短一次:

return type(self) == type(other) and self.container.__eq__(other.container)

编辑:根据mglisons评论:

通过使用常规的相等语句,可以使其更加pythonic:

return type(self) == type(other) and self.container == other.container

他们还提出了关于使用类型检查eaulity的一个好点.如果您确定Queue永远不会被子类化(这很难说明).您可以使用异常处理来有效捕获AttributeError,如下所示:

def __eq__(self, other):
    try:
        return self.container == other.container
    except AttributeError:
        return False    # There is no 'container' attribute, so can't be equal
    except:
        raise           # Another error occured, better pay it forward

以上可能被认为有点过度设计,但从安全性和可恢复性的角度来看,这可能是解决这个问题的更好方法之一.

或者使用hasattr的更好,更短的方法(我最初应该考虑过)是:

return hasattr(other, 'container') and self.container == other.container

标签:python,class,object,equals,comparison
来源: https://codeday.me/bug/20190825/1718165.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有