gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-03 13:46:04 25 4
gpt4 key购买 nike

我正在为 python 编写一个 Queue 数据结构,纯粹出于学习目的。这是我的。当我比较两个 Queue 对象是否相等时,出现错误。我认为错误会弹出,因为我没有在我的 __eq__ 中比较 None 。但是我如何检查 Nonereturn 相应地。事实上,我在幕后使用 list 并调用它的 __eq__,认为它应该像这里所示那样小心,但它没有

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

这是我的类(class):

@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)

但是otherNone ,这意味着 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)

如果 other 会延迟计算是None , 并返回 False在评估 and 之后的表达式部分之前.否则,它将执行评估。但是,如果 other,您将遇到其他问题不是 Queue 类型(或者更准确地说,另一个对象没有 container 属性),例如:

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

所以...取决于您的逻辑,如果 Queue不能与其他类型“相等”(这只有你能说),你可以像这样检查正确的类型:

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

但是... NoneNoneType , 因此它永远不可能与 Queue 属于同一类型.所以我们可以再次将其缩短为:

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

编辑:根据 mglisons 的评论:

这可以通过使用常规的相等语句变得更加 pythonic:

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

他们还就 type 的使用提出了一个很好的观点在检查美丽。如果你确定 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 - 如何比较 python 自定义类中 None 对象的相等性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20364414/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com