我想为以下类创建一个通用的__eq__()
方法。基本上我希望能够添加另一个属性(nick
)而无需更改__eq__()
我想我可以通过迭代dir()
以某种方式做到这一点,但我想知道是否有办法创建一个只提供属性的理解。
class Person:
def __init__(self, first, last):
self.first=first
self.last=last
@property
def first(self):
assert(self._first != None)
return self._first
@first.setter
def first(self,fn):
assert(isinstance(fn,str))
self._first=fn
@property
def last(self):
assert(self._last != None)
return self._last
@last.setter
def last(self,ln):
assert(isinstance(ln,str))
self._last=ln
@property
def full(self):
return f'{self.first} {self.last}'
def __eq__(self, other):
return self.first==other.first and self.last==other.last
p = Person('Raymond', 'Salemi')
p2= Person('Ray', 'Salemi')
答案 0 :(得分:7)
您可以使用__dict__
来检查所有属性是否相同,以及所有属性的缩放:
如果对象不匹配类型,我只需返回False
。
class Person:
def __init__(self, first, last, nick):
self.first = first
self.last = last
self.nick = nick
def __eq__(self, other):
return self.__dict__ == other.__dict__ if type(self) == type(other) else False
>>> p = Person('Ray', 'Salemi', 'Ray')
>>> p2= Person('Ray', 'Salemi', 'Ray')
>>> p3 = Person('Jared', 'Salemi', 'Jarbear')
>>> p == p2
True
>>> p3 == p2
False
>>> p == 1
False
答案 1 :(得分:2)
您可以使用以下结构获取Class
的所有属性:
from itertools import chain
@classmethod
def _properties(cls):
type_dict = dict(chain.from_iterable(typ.__dict__.items() for typ in reversed(cls.mro())))
return {k for k, v in type_dict.items() if 'property' in str(v)}
__eq__
会变成这样:
def __eq__(self, other):
properties = self._properties() & other._properties()
if other._properties() > properties and self._properties() > properties:
# types are not comparable
return False
try:
return all(getattr(self, prop) == getattr(other, prop) for prop in properties)
except AttributeError:
return False
使用reversed(cls.mro())
的原因是这样的:
class Worker(Person):
@property
def wage(self):
return 0
p4 = Worker('Raymond', 'Salemi')
print(p4 == p3)
True
答案 2 :(得分:-1)
你可以尝试这样做,如果你想在dict中设置eq并设置
,它也会工作def __eq__(self, other):
"""Overrides the default implementation"""
if isinstance(self, other.__class__):
return self.__hash__() == other.__hash__()
return NotImplemented
def __hash__(self):
"""Overrides the default implementation,
and set which fieds to use for hash generation
"""
__make_hash = [
self.first
]
return hash(tuple(sorted(list(filter(None, __make_hash)))))