프로그래밍미들 Python 개발자

비교 연산자 '=='와 Python의 __eq__ 메소드의 동작은 무엇에 의해 결정됩니까? 사용자 정의 클래스의 비교 동작을 어떻게 변경할 수 있습니까?

Hintsage AI 어시스턴트로 면접 통과

답변.

문제의 역사:

Python에서 객체를 값으로 비교할 때 연산자 '=='가 사용되며, 이는 내부적으로 eq 메소드를 호출합니다. 이 메소드의 기본 동작은 object에서 상속되며, 객체의 동일성을 비교합니다(대부분의 클래스에 대해).

문제:

사용자 정의 클래스의 인스턴스가 의미 있게 비교되기를 원할 때(예를 들어, 동일한 데이터 세트를 가진 두 개의 서로 다른 Person 객체가 같다고 간주될 경우) 기본 동작은 불충분합니다 — 비교 방법을 명시적으로 정의해야 합니다.

해결책:

'=='의 동작을 변경하려면 자신의 클래스에서 eq 메소드를 재정의해야 합니다. 클래스가 해시 가능한 경우, __hash__도 재정의해야 합니다.

코드 예:

class Person: def __init__(self, name, age): self.name = name self.age = age def __eq__(self, other): if not isinstance(other, Person): return NotImplemented return self.name == other.name and self.age == other.age p1 = Person("Ann", 25) p2 = Person("Ann", 25) print(p1 == p2) # True

핵심 사항:

  • '=='는 __eq__를 호출합니다.
  • __eq__가 없는 객체는 그들의 동일성(id)을 비교합니다.
  • 집합/사전에서 올바르게 작동하려면 __hash__도 구현해야 합니다.

덫이 있는 질문들.

서로 다른 타입의 객체에 대해 '==' 비교가 항상 대칭적입니까?

반드시 그렇지는 않습니다 — 첫 번째 객체가 NotImplemented를 반환하면, 반대 비교가 호출됩니다. 그렇지 않으면 비대칭이 발생할 수 있습니다.

class A: def __eq__(self, other): return True class B: pass print(A() == B()) # True print(B() == A()) # False

__eq__를 구현하지 않으면, 같은 사용자 정의 클래스의 객체들은 어떻게 비교됩니까?

id(메모리에서의 동일성, 속성 값이 아닌)를 비교합니다.

class Foo: def __init__(self, x): self.x = x f1 = Foo(5) f2 = Foo(5) print(f1 == f2) # False

딕셔너리의 키로 사용해야 하는 객체에 대해 hash 없이 __eq__를 정의할 수 있습니까?

아니요. __eq__가 변경된 경우, __hash__도 정의하는 것이 바람직합니다. 그렇지 않으면 객체가 해시 가능하지 않게 되어 TypeError가 발생합니다.

class Foo: def __eq__(self, other): return True # 해시는 object에서 상속되지만, 동작이 예측할 수 없게 됩니다. # __hash__를 명시적으로 정의하는 것이 좋습니다.

일반적인 오류와 안티 패턴

  • dict/set에서 키가 필요할 때 hash 없이 eq 구현.
  • 다른 타입의 객체와 비교할 때 오류(반드시 NotImplemented를 반환해야 하며, False 아님).
  • __eq__와 __hash__의 불일치한 정의로 인해 해시 구조에서 잘못된 동작이 발생함.

실생활 예시

부정적인 사례

ValueObject 클래스를 설계할 때 __eq__만 구현하고 __hash__를 고려하지 못하여, 이 객체를 딕셔너리의 키 또는 집합의 요소로 사용할 때 TypeError 예외가 발생했습니다.

장점:

사용자 비교의 빠른 도입.

단점:

집합과 딕셔너리에서 객체를 사용할 수 없으며, 디버깅이 어렵습니다.

긍정적인 사례

다른 프로젝트에서 개발자들은 두 메소드(__eq__와 hash)를 명시적으로 구현하고, 두 객체가 __eq__에 의해 같으면 그들의 해시도 같아야 한다는 규칙을 엄격히 따랐습니다.

장점:

해시 구조가 올바로 작동하며, 일관된 동작과 유지 관리의 용이함.

단점:

값이 같은 객체가 해시 컨테이너에서 구별되지 않기 때문에 유연성이 감소합니다.