파이썬에서 객체 인스턴스가 속성에 의해 동일한 지 비교
나는 수업이 MyClass
두 멤버 변수가 포함되어, foo
및 bar
:
class MyClass:
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
나는에 대해 동일한 값을 가지고 각각의이 클래스의 두 인스턴스가 foo
와를 bar
:
x = MyClass('foo', 'bar')
y = MyClass('foo', 'bar')
그러나 동등성을 비교하면 Python은 False
다음을 반환합니다 .
>>> x == y
False
파이썬 이이 두 객체를 동등하게 생각하게하려면 어떻게해야합니까?
메소드를 구현해야합니다 __eq__
.
class MyClass:
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __eq__(self, other):
if not isinstance(other, MyClass):
# don't attempt to compare against unrelated types
return NotImplemented
return self.foo == other.foo and self.bar == other.bar
이제 출력합니다 :
>>> x == y
True
구현 __eq__
하면 클래스의 인스턴스를 해시 할 수 없게되므로 세트와 딕트에 저장할 수 없습니다. 당신은 불변의 유형을 모델링하지 않는 경우 (즉, 속성 경우 foo
와 bar
개체의 수명 내에서 값을 변경할 수 있음), 다음은 그냥 unhashable로 인스턴스를두고하는 것이 좋습니다.
불변 유형을 모델링하는 경우 datamodel 후크도 구현해야합니다 __hash__
.
class MyClass:
...
def __hash__(self):
# necessary for instances to behave sanely in dicts and sets.
return hash((self.foo, self.bar))
__dict__
값 을 반복 하고 비교 하는 아이디어와 같은 일반적인 솔루션 은 권장되지 않습니다. __dict__
비교할 수 없거나 해시 할 수없는 유형이 포함되어 있기 때문에 실제로는 결코 일반적인 방법이 될 수 없습니다 .
N.B.: be aware that before Python 3, you may need to use __cmp__
instead of __eq__
. Python 2 users may also want to implement __ne__
, since a sensible default behaviour for inequality (i.e. inverting the equality result) will not be automatically created in Python 2.
You override the rich comparison operators in your object.
class MyClass:
def __lt__(self, other):
# return comparison
def __le__(self, other):
# return comparison
def __eq__(self, other):
# return comparison
def __ne__(self, other):
# return comparison
def __gt__(self, other):
# return comparison
def __ge__(self, other):
# return comparison
Like this:
def __eq__(self, other):
return self._id == other._id
Implement the __eq__
method in your class; something like this:
def __eq__(self, other):
return self.path == other.path and self.title == other.title
Edit: if you want your objects to compare equal if and only if they have equal instance dictionaries:
def __eq__(self, other):
return self.__dict__ == other.__dict__
As a summary :
- It's advised to implement
__eq__
rather than__cmp__
, except if you run python <= 2.0 (__eq__
has been added in 2.1) - Don't forget to also implement
__ne__
(should be something likereturn not self.__eq__(other)
orreturn not self == other
except very special case) - Don`t forget that the operator must be implemented in each custom class you want to compare (see example below).
If you want to compare with object that can be None, you must implement it. The interpreter cannot guess it ... (see example below)
class B(object): def __init__(self): self.name = "toto" def __eq__(self, other): if other is None: return False return self.name == other.name class A(object): def __init__(self): self.toto = "titi" self.b_inst = B() def __eq__(self, other): if other is None: return False return (self.toto, self.b_inst) == (other.toto, other.b_inst)
When comparing instances of objects, the __cmp__
function is called.
If the == operator is not working for you by default, you can always redefine the __cmp__
function for the object.
Edit:
As has been pointed out, the __cmp__
function is deprecated since 3.0. Instead you should use the “rich comparison” methods.
Depending on your specific case, you could do:
>>> vars(x) == vars(y)
True
See Python dictionary from an object's fields
If you want to get an attribute-by-attribute comparison, and see if and where it fails, you can use the following list comprehension:
[i for i,j in
zip([getattr(obj_1, attr) for attr in dir(obj_1)],
[getattr(obj_2, attr) for attr in dir(obj_2)])
if not i==j]
The extra advantage here is that you can squeeze it one line and enter in the "Evaluate Expression" window when debugging in PyCharm.
I tried the initial example (see 7 above) and it did not work in ipython. Note that cmp(obj1,obj2) returns a "1" when implemented using two identical object instances. Oddly enough when I modify one of the attribute values and recompare, using cmp(obj1,obj2) the object continues to return a "1". (sigh...)
Ok, so what you need to do is iterate two objects and compare each attribute using the == sign.
Instance of a class when compared with == comes to non-equal. The best way is to ass the cmp function to your class which will do the stuff.
If you want to do comparison by the content you can simply use cmp(obj1,obj2)
In your case cmp(doc1,doc2) It will return -1 if the content wise they are same.
'IT story' 카테고리의 다른 글
@ Scripts.Render (“~ / bundles / jquery”)를 사용해야하는 이유 (0) | 2020.04.28 |
---|---|
uint8_t vs unsigned char (0) | 2020.04.28 |
.NET 표준 및 .NET Core (0) | 2020.04.28 |
스택 스매싱 감지 (0) | 2020.04.28 |
함수 이름 주위의 괄호는 무엇을 의미합니까? (0) | 2020.04.28 |