Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 클래스에서 동등성(==) 연산자를 올바르게 사용하는 방법

파이썬 클래스 객체를 == 연산자로 비교하면 왜 False가 나올까?

사용자 정의 클래스의 인스턴스 두 개를 만들고 아래 코드처럼 등가(equality) 연산자 ==로 비교하면, 겉보기에는 같은 값을 가졌음에도 불구하고 결과는 False로 출력됩니다.

class Integer:
    def __init__(self, number):
        self.number = number

n1 = Integer(1)
n2 = Integer(1)
print bool(n1 == n2)

출력 결과:

False

원인: 기본 비교는 '객체 식별자' 기준

파이썬은 별도의 설정이 없을 경우 비교 연산 시 객체 자체의 값이 아니라 객체 식별자(identity), 즉 메모리상의 참조 위치를 기준으로 판단합니다. n1n2는 서로 다른 인스턴스이므로 식별자가 다르고, 그 결과 False가 반환되는 것입니다.

해결 방법: __eq__ 메서드 오버라이딩

이 문제를 해결하려면 클래스 내에서 __eq__ 메서드를 직접 오버라이딩하여 값 기반의 비교 로직을 정의해야 합니다.

class Integer:
    def __init__(self, number):
        self.number = number

    def __eq__(self, other):
        if isinstance(self, other.__class__):
            return self.__dict__ == other.__dict__
        return False

n1 = Integer(1)
n2 = Integer(1)
print bool(n1 == n2)
print bool(n1 != n2)

출력 결과:

True
True

위 예제에서는 두 객체의 내부 속성 딕셔너리(__dict__)를 비교하여 값이 같으면 True를 반환하도록 구현했습니다.

Python 2.x와 3.x의 차이점: __ne__ 처리

Python 2.x에서는 !=(부등가) 연산이 올바르게 동작하도록 하려면 __ne__ 메서드도 함께 오버라이딩해야 합니다. 반면 Python 3.x에서는 이 작업이 필요하지 않습니다.

공식 문서에 따르면 다음 사항이 성립합니다:

기본적으로 __ne__()__eq__()에 위임(delegate)하여 그 결과를 반전시킵니다. 단, 결과가 NotImplemented인 경우는 제외됩니다. 비교 연산자들 사이에는 이 외에 어떠한 암묵적인 관계도 존재하지 않습니다. 예를 들어, (x < y or x == y)가 참이라고 해서 x <= y가 참이 되는 것은 아닙니다.

정리하면, 파이썬 3 이상 환경에서는 __eq__만 정의해도 ==!= 모두 일관되게 동작하지만, 파이썬 2 환경을 지원해야 한다면 __ne__까지 명시적으로 구현하는 것이 안전합니다.