Python 역방향 연산자란 무엇인가?
Python에서 역방향(reversed) 연산자는 이항 연산자가 호출될 때 좌항과 우항 중 어느 쪽의 메서드가 실행되는지를 결정하는 특수 메서드입니다. 예를 들어 &(집합 교집합) 연산자는 다음과 같이 동작합니다.
s & z → s.__and__(z) 호출
z & s → s.__rand__(z) 호출즉, 일반 연산자 메서드(__and__, __add__, __or__ 등)가 먼저 시도되고, 이것이 실패하면 피연산자의 순서를 뒤바꾼 역방향 메서드(__rand__, __radd__, __ror__ 등)가 대신 실행됩니다.
단순 객체에는 큰 의미가 없다
일반적인 숫자나 문자열처럼 단순한 객체의 덧셈, 논리곱 같은 기본 연산에서는 역방향 연산자가 크게 와닿지 않습니다. a + b와 b + a가 같은 결과를 내는 교환 법칙이 성립하는 경우가 많기 때문입니다.
상속 구조에서 빛을 발하는 역방향 연산자
역방향 연산자가 진가를 발휘하는 순간은 바로 상속(inheritance) 상황입니다. Python은 우측 피연산자가 좌측 피연산자의 서브클래스(subclass)일 경우, 일반 연산보다 역방향 연산을 먼저 시도합니다.
이 규칙 덕분에 부모 클래스와 자식 클래스가 서로 다른 연산 구현을 가지고 있을 때, 더 구체적인 자식 클래스의 로직이 우선적으로 적용될 수 있습니다. 예를 들어 부모 클래스의 __and__와 자식 클래스의 __rand__에 각각 다른 동작을 정의해 두면, 자식 인스턴스가 우항에 올 때 자식의 방식으로 연산이 처리됩니다.
NotImplemented 반환 시의 폴백(fallback) 메커니즘
역방향 연산자가 사용되는 또 다른 핵심 경우는 첫 번째 피연산자의 메서드가 NotImplemented를 반환할 때입니다.
class A:
def __and__(self, other):
return NotImplemented # 지원하지 않음
class B:
def __rand__(self, other):
return "B 타입의 교집합 연산"
a = A()
b = B()
print(a & b) # A.__and__가 NotImplemented 반환 → B.__rand__가 실행됨위 코드처럼 A 객체가 & 연산을 지원하지 않아 NotImplemented를 반환하면, Python은 자동으로 B.__rand__를 호출해 연산을 재시도합니다. 이러한 폴백 메커니즘 덕분에 서로 다른 타입 간의 연산도 유연하게 처리할 수 있습니다.
정리
- 역방향 연산자(
__r*__)는 피연산자 순서를 뒤집어 호출되는 특수 메서드입니다. - 우항이 좌항의 서브클래스라면 역방향 연산이 먼저 시도되어, 자식 클래스의 구현이 우선 적용됩니다.
- 첫 번째 피연산자가
NotImplemented를 반환하면 역방향 메서드가 폴백으로 실행됩니다. - 주로 상속 구조와 이종 타입 간 연산 지원에 유용하게 활용됩니다.