프로그래밍에서 연산자(operator)란 덧셈, 뺄셈, 비교 등 특정 작업을 수행하기 위해 미리 정의된 기호(키)를 의미합니다. Python은 산술, 비교, 비트 단위, 멤버십 등 다양한 범주로 나뉜 방대한 내장 연산자 세트를 제공합니다.
Python 표준 라이브러리의 operator 모듈은 이러한 내장 연산자에 대응하는 함수들로 구성되어 있습니다. 함수 이름은 해당 연산자의 종류와 유사하게 지어져 있어 직관적입니다. 예를 들어 operator 모듈의 add() 함수는 + 연산자에 대응합니다.
한편 Python의 Object 클래스에는 연산자 기호에 대응하는 듀더(dunder) 메서드, 즉 이름 앞뒤에 이중 밑줄이 붙은 메서드가 존재합니다. 이러한 듀더 메서드를 사용자 정의 클래스에서 적절히 오버로드하면 연산자 오버로딩을 구현할 수 있습니다. operator 모듈에도 이에 대응하는 듀더 함수들이 포함되어 있는데, 예를 들어 add()와 __add__()는 모두 + 기호의 연산을 수행합니다.
먼저 operator 모듈의 함수들을 임포트해 보겠습니다.
>>> from operator import *
산술 연산자에 대응하는 함수
산술 연산자에 대응하는 함수들을 살펴보기 위해 두 변수를 초기화합니다.
>>> a = 10 >>> b = 20
add(), sub(), mul()은 각각 +, -, * 연산자에 대응하며, 나눗셈 기호 /는 truediv() 함수로 구현됩니다.
>>> add(a,b) 30 >>> a + b 30 >>> sub(a,b) -10 >>> a - b -10 >>> mul(a,b) 200 >>> a * b 200 >>> truediv(a,b) 0.5 >>> a / b 0.5
그 외 산술 연산자인 %, **, //는 각각 mod(), pow(), floordiv() 함수로 구현됩니다.
>>> a = 5 >>> b = 3 >>> a % b 2 >>> mod(a,b) 2 >>> a ** b 125 >>> pow(a,b) 125 >>> a // b 1 >>> floordiv(a,b) 1
비교 연산자에 대응하는 함수
논리적 비교를 수행하는 연산자 <, <=, >, >=, ==, !=는 각각 lt(), le(), gt(), ge(), eq(), ne() 함수로 구현됩니다.
>>> a = 5 >>> b = 7 >>> a < b True >>> lt(a,b) True >>> a <= b True >>> le(a,b) True >>> a > b False >>> gt(a,b) False >>> a >= b False >>> ge(a,b) False >>> a == b False >>> eq(a,b) False >>> a != b True >>> ne(a,b) True
시퀀스와 함께 사용하는 함수
Python의 내장 연산자인 in, +(연결), del은 각각 contains(), concat(), delitem() 함수로 구현됩니다. 또한 인덱스 할당 연산자 seq[x] = y에는 setitem() 함수가, seq[x]의 값을 조회할 때는 getitem() 함수가 사용됩니다.
>>> a = [1,2,3] >>> b = ['a','b','c'] >>> a + b # 시퀀스 연결 [1, 2, 3, 'a', 'b', 'c'] >>> concat(a,b) [1, 2, 3, 'a', 'b', 'c'] >>> contains(a,'2') # in 연산자 구현 False >>> contains(a,2) True >>> 2 in a True >>> b[1] = 'x' # setitem()으로 구현되는 인덱스 할당 >>> b ['a', 'x', 'c'] >>> setitem(b,1,'b') >>> b ['a', 'b', 'c'] >>> a[1] # getitem()으로 구현되는 값 조회 2 >>> getitem(a,1) 2 >>> del b[2] # delitem()에 해당하는 요소 삭제 >>> b ['a', 'b'] >>> delitem(a,2) >>> a [1, 2]
제자리(in-place) 연산자 함수
할당과 계산을 한 단계에서 동시에 수행하는 연산자를 제자리(in-place) 연산자라고 합니다. Python의 제자리 연산자 역시 operator 모듈의 대응 함수로 구현할 수 있습니다. 예를 들어 덧셈과 할당을 동시에 수행하는 += 연산자에는 iadd() 함수가 대응되며, 마찬가지로 각 연산자 함수 앞에 i를 붙이면 그 제자리 버전이 됩니다.
제자리 덧셈
>>> a = 10 >>> b = 20 >>> a = iadd(a,b) # a += b와 동일 >>> a 30
제자리 뺄셈
>>> a = 10 >>> b = 20 >>> a = isub(a,b) # a -= b와 동일 >>> a -10
제자리 곱셈
>>> a = 10 >>> b = 20 >>> a = imul(a,b) # a *= b와 동일 >>> a 200
제자리 나눗셈
>>> a = 10 >>> b = 4 >>> a = itruediv(a,b) >>> a 2.5
비트 단위 연산자에 대응하는 함수
operator 모듈에는 표준 비트 단위(bit-wise) 연산자를 구현하는 함수들도 포함되어 있습니다.
>>> and_(10,2) # 10 & 2와 동일 2 >>> or_(10,2) # 10 | 2와 동일 10 >>> xor(10,2) # 10 ^ 2와 동일 8 >>> lshift(10,2) # 10 << 2와 동일 40 >>> rshift(10,2) # 10 >> 2와 동일 2