operator — 표준 연산자를 함수로
operator — 표준 연산자를 함수로
operator 모듈은 Python의 고유 연산자에 해당하는 효율적인 함수 집합을 내보내요. 예를 들어 operator.add(x, y)는 표현식 x+y와 동등해요. 많은 함수 이름이 특수 메서드에 사용되는 이름에서 이중 밑줄을 뺀 것이에요. 하위 호환을 위해 이들 중 많은 것에 이중 밑줄을 유지한 변형이 있어요. 명확성을 위해 이중 밑줄이 없는 변형이 선호돼요.
함수는 객체 비교, 논리 연산, 수학 연산, 시퀀스 연산을 수행하는 범주로 나뉘어요.
출처: Python 표준 라이브러리
본문
객체 비교 함수는 모든 객체에 유용하고, 그들이 지원하는 풍부한 비교(rich comparison) 연산자의 이름을 따서 지었어요.
operator.lt(a, b), operator.le(a, b), operator.eq(a, b), operator.ne(a, b), operator.ge(a, b), operator.gt(a, b)와 __lt__, __le__, __eq__, __ne__, __ge__, __gt__ 변형
a와 b 사이에 "풍부한 비교"를 수행해요. 구체적으로 lt(a, b)는 a < b와, le(a, b)는 a <= b와, eq(a, b)는 a == b와, ne(a, b)는 a != b와, gt(a, b)는 a > b와, ge(a, b)는 a >= b와 동등해요. 이 함수들은 불리언 값으로 해석될 수도 있고 아닐 수도 있는 어떤 값이든 돌려줄 수 있음에 주의하세요. 풍부한 비교에 대한 자세한 내용은 Comparisons를 참고하세요.
논리 연산도 일반적으로 모든 객체에 적용 가능하고, 진리 테스트, 동일성 테스트, 불리언 연산을 지원해요.
operator.not_(obj), operator.not(obj)
not obj의 결과를 돌려줘요. (객체 인스턴스에는 __not__() 메서드가 없음에 주의하세요. 이 연산을 정의하는 건 인터프리터 코어뿐이에요. 결과는 __bool__()과 __len__() 메서드의 영향을 받아요.)
operator.truth(obj)
obj가 참이면 True, 아니면 False를 돌려줘요. bool 생성자를 사용하는 것과 동등해요.
operator.is_(a, b)
a is b를 돌려줘요. 객체 동일성을 테스트해요.
operator.is_not(a, b)
a is not b를 돌려줘요. 객체 동일성을 테스트해요.
operator.is_none(a)
a is None을 돌려줘요. 객체 동일성을 테스트해요. 버전 3.14에 추가됨.
operator.is_not_none(a)
a is not None을 돌려줘요. 객체 동일성을 테스트해요. 버전 3.14에 추가됨.
수학 및 비트 연산이 가장 많아요.
operator.abs(obj), operator.abs(obj)
obj의 절댓값을 돌려줘요.
operator.add(a, b), operator.add(a, b)
숫자 a와 b에 대해 a + b를 돌려줘요.
operator.and_(a, b), operator.and(a, b)
a & b를 돌려줘요.
operator.floordiv(a, b), operator.floordiv(a, b)
a // b를 돌려줘요.
operator.index(a), operator.index(a)
정수로 변환된 a를 돌려줘요. a.__index__()와 동등해요.
버전 3.10에서 변경: 결과가 항상 정확한 타입 int. 이전에는 결과가 int의 하위 클래스 인스턴스일 수 있었음.
operator.inv(obj), operator.invert(obj), operator.inv(obj), operator.invert(obj)
~obj를 돌려줘요.
operator.lshift(a, b), operator.lshift(a, b)
a << b를 돌려줘요.
operator.mod(a, b), operator.mod(a, b)
a % b를 돌려줘요.
operator.mul(a, b), operator.mul(a, b)
a * b를 돌려줘요.
operator.matmul(a, b), operator.matmul(a, b)
a @ b를 돌려줘요. 버전 3.5에 추가됨.
operator.neg(obj), operator.neg(obj)
부정된 obj(-obj)를 돌려줘요.
operator.or_(a, b), operator.or(a, b)
a | b를 돌려줘요.
operator.pos(obj), operator.pos(obj)
+obj를 돌려줘요.
operator.pow(a, b), operator.pow(a, b)
a ** b를 돌려줘요.
operator.rshift(a, b), operator.rshift(a, b)
a >> b를 돌려줘요.
operator.sub(a, b), operator.sub(a, b)
a - b를 돌려줘요.
operator.truediv(a, b), operator.truediv(a, b)
2/3이 0이 아니라 .66이 되는 a / b를 돌려줘요. "진 나눗셈(true division)"이라고도 불러요.
operator.xor(a, b), operator.xor(a, b)
a ^ b를 돌려줘요.
시퀀스(일부는 매핑과도)로 동작하는 연산은 다음을 포함해요.
operator.concat(a, b), operator.concat(a, b)
시퀀스 a와 b에 대해 a + b를 돌려줘요.
operator.contains(a, b), operator.contains(a, b)
테스트 b in a의 결과를 돌려줘요. 피연산자가 뒤집혔음을 주의하세요.
operator.countOf(a, b)
a에서 b의 발생 횟수를 돌려줘요.
operator.delitem(a, b), operator.delitem(a, b)
인덱스 b에 있는 a의 값을 제거해요.
operator.getitem(a, b), operator.getitem(a, b)
인덱스 b에 있는 a의 값을 돌려줘요.
operator.indexOf(a, b)
a에서 b의 첫 발생 인덱스를 돌려줘요.
operator.setitem(a, b, c), operator.setitem(a, b, c)
인덱스 b에 있는 a의 값을 c로 설정해요.
operator.length_hint(obj, default=0)
객체 obj의 추정 길이를 돌려줘요. 먼저 실제 길이를 돌려주려 시도하고, 그다음 object.__length_hint__()를 사용한 추정, 마지막으로 기본값을 돌려줘요. 버전 3.4에 추가됨.
다음 연산은 callable과 동작해요.
operator.call(obj, /, *args, **kwargs), operator.call(obj, /, *args, **kwargs)
obj(*args, **kwargs)를 돌려줘요. 버전 3.11에 추가됨.
operator 모듈은 일반화된 속성·항목 조회 도구도 정의해요. 이것들은 map(), sorted(), itertools.groupby() 또는 함수 인자를 기대하는 다른 함수의 인자로 빠른 필드 추출기를 만드는 데 유용해요.
operator.attrgetter(attr), operator.attrgetter(*attrs)
피연산자에서 attr을 가져오는 callable 객체를 돌려줘요. 속성을 두 개 이상 요청하면 속성의 튜플을 돌려줘요. 속성 이름은 점을 포함할 수도 있어요. 예:
f = attrgetter('name')후에f(b)호출은b.name을 돌려줘요.f = attrgetter('name', 'date')후에f(b)호출은(b.name, b.date)을 돌려줘요.f = attrgetter('name.first', 'name.last')후에f(b)호출은(b.name.first, b.name.last)을 돌려줘요.
동등한 함수:
def attrgetter(*items):
if any(not isinstance(item, str) for item in items):
raise TypeError('attribute name must be a string')
if len(items) == 1:
attr = items[0]
def g(obj):
return resolve_attr(obj, attr)
else:
def g(obj):
return tuple(resolve_attr(obj, attr) for attr in items)
return g
def resolve_attr(obj, attr):
for name in attr.split("."):
obj = getattr(obj, name)
return obj
operator.itemgetter(item), operator.itemgetter(*items)
피연산자의 __getitem__() 메서드를 사용해 피연산자에서 item을 가져오는 callable 객체를 돌려줘요. 여러 항목을 지정하면 조회 값의 튜플을 돌려줘요. 예:
f = itemgetter(2)후에f(r)호출은r[2]를 돌려줘요.g = itemgetter(2, 5, 3)후에g(r)호출은(r[2], r[5], r[3])을 돌려줘요.
동등한 함수:
def itemgetter(*items):
if len(items) == 1:
item = items[0]
def g(obj):
return obj[item]
else:
def g(obj):
return tuple(obj[item] for item in items)
return g
항목은 피연산자의 __getitem__() 메서드가 받아들이는 어떤 타입이든 될 수 있어요. 딕셔너리는 어떤 해시 가능한 값도 받아들여요. 리스트, 튜플, 문자열은 인덱스나 슬라이스를 받아들여요:
>>> itemgetter(1)('ABCDEFG')
'B'
>>> itemgetter(1, 3, 5)('ABCDEFG')
('B', 'D', 'F')
>>> itemgetter(slice(2, None))('ABCDEFG')
'CDEFG'
>>> soldier = dict(rank='captain', name='dotterbart')
>>> itemgetter('rank')(soldier)
'captain'
itemgetter()를 사용해 튜플 레코드에서 특정 필드를 검색하는 예:
>>> inventory = [('apple', 3), ('banana', 2), ('pear', 5), ('orange', 1)]
>>> getcount = itemgetter(1)
>>> list(map(getcount, inventory))
[3, 2, 5, 1]
>>> sorted(inventory, key=getcount)
[('orange', 1), ('banana', 2), ('apple', 3), ('pear', 5)]
operator.methodcaller(name, /, *args, **kwargs)
피연산자에서 메서드 name을 호출하는 callable 객체를 돌려줘요. 추가 인자 및/또는 키워드 인자도 주어지면 메서드에도 그들이 주어져요. 예:
f = methodcaller('name')후에f(b)호출은b.name()을 돌려줘요.f = methodcaller('name', 'foo', bar=1)후에f(b)호출은b.name('foo', bar=1)을 돌려줘요.
동등한 함수:
def methodcaller(name, /, *args, **kwargs):
def caller(obj):
return getattr(obj, name)(*args, **kwargs)
return caller
연산자를 함수로 매핑
이 표는 추상 연산이 Python 문법의 연산자 기호와 operator 모듈의 함수에 어떻게 대응하는지 보여 줘요.
| 연산 | 문법 | 함수 |
|---|---|---|
| 덧셈 | a + b | add(a, b) |
| 이어붙이기 | seq1 + seq2 | concat(seq1, seq2) |
| 포함 테스트 | obj in seq | contains(seq, obj) |
| 나눗셈 | a / b | truediv(a, b) |
| 나눗셈 | a // b | floordiv(a, b) |
| 비트 And (교집합) | a & b | and_(a, b) |
| 비트 배타적 Or (대칭 차) | a ^ b | xor(a, b) |
| 비트 반전 (보수) | ~ a | invert(a) |
| 비트 Or (합집합) | a | b | or_(a, b) |
| 지수 | a ** b | pow(a, b) |
| 동일성 | a is b | is_(a, b) |
| 동일성 | a is not b | is_not(a, b) |
| 동일성 | a is None | is_none(a) |
| 동일성 | a is not None | is_not_none(a) |
| 인덱스 할당 | obj[k] = v | setitem(obj, k, v) |
| 인덱스 삭제 | del obj[k] | delitem(obj, k) |
| 인덱싱 | obj[k] | getitem(obj, k) |
| 왼쪽 시프트 | a << b | lshift(a, b) |
| 모듈로 | a % b | mod(a, b) |
| 곱셈 | a * b | mul(a, b) |
| 행렬 곱셈 | a @ b | matmul(a, b) |
| 부정 (산술) | - a | neg(a) |
| 부정 (논리) | not a | not_(a) |
| 양수 | + a | pos(a) |
| 오른쪽 시프트 | a >> b | rshift(a, b) |
| 슬라이스 할당 | seq[i:j] = values | setitem(seq, slice(i, j), values) |
| 슬라이스 삭제 | del seq[i:j] | delitem(seq, slice(i, j)) |
| 슬라이싱 | seq[i:j] | getitem(seq, slice(i, j)) |
| 문자열 형식화 | s % obj | mod(s, obj) |
| 뺄셈 | a - b | sub(a, b) |
| 진리 테스트 | obj | truth(obj) |
| 순서 | a < b | lt(a, b) |
| 순서 | a <= b | le(a, b) |
| 동등성 | a == b | eq(a, b) |
| 차이 | a != b | ne(a, b) |
| 순서 | a >= b | ge(a, b) |
| 순서 | a > b | gt(a, b) |
In-place 연산자
많은 연산에 "in-place" 버전이 있어요. 아래 나열된 함수는 평소 문법보다 in-place 연산자에 더 원시적인 접근을 제공해요. 예를 들어 문 x += y는 x = operator.iadd(x, y)와 동등해요. 다르게 말하면 z = operator.iadd(x, y)는 복합 문 z = x; z += y와 동등하다고 할 수 있어요.
이 예들에서 in-place 메서드가 호출될 때 계산과 할당이 두 개의 분리된 단계로 수행됨에 주의하세요. 아래 나열된 in-place 함수는 첫 단계만 수행해 in-place 메서드를 호출해요. 두 번째 단계인 할당은 처리되지 않아요.
문자열, 숫자, 튜플 같은 불변 대상에 대해 갱신된 값이 계산되지만 입력 변수에 다시 할당되지는 않아요:
>>> a = 'hello'
>>> iadd(a, ' world')
'hello world'
>>> a
'hello'
리스트와 딕셔너리 같은 가변 대상에 대해 in-place 메서드가 갱신을 수행하므로 후속 할당이 필요 없어요:
>>> s = ['h', 'e', 'l', 'l', 'o']
>>> iadd(s, [' ', 'w', 'o', 'r', 'l', 'd'])
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
>>> s
['h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd']
operator.iadd(a, b)/__iadd__(a, b)—a = iadd(a, b)는a += b와 동등.operator.iand(a, b)/__iand__(a, b)—a = iand(a, b)는a &= b와 동등.operator.iconcat(a, b)/__iconcat__(a, b)—a = iconcat(a, b)는 시퀀스 a와 b에 대해a += b와 동등.operator.ifloordiv(a, b)/__ifloordiv__(a, b)—a = ifloordiv(a, b)는a //= b와 동등.operator.ilshift(a, b)/__ilshift__(a, b)—a = ilshift(a, b)는a <<= b와 동등.operator.imod(a, b)/__imod__(a, b)—a = imod(a, b)는a %= b와 동등.operator.imul(a, b)/__imul__(a, b)—a = imul(a, b)는a *= b와 동등.operator.imatmul(a, b)/__imatmul__(a, b)—a = imatmul(a, b)는a @= b와 동등. 버전 3.5에 추가됨.operator.ior(a, b)/__ior__(a, b)—a = ior(a, b)는a |= b와 동등.operator.ipow(a, b)/__ipow__(a, b)—a = ipow(a, b)는a **= b와 동등.operator.irshift(a, b)/__irshift__(a, b)—a = irshift(a, b)는a >>= b와 동등.operator.isub(a, b)/__isub__(a, b)—a = isub(a, b)는a -= b와 동등.operator.itruediv(a, b)/__itruediv__(a, b)—a = itruediv(a, b)는a /= b와 동등.operator.ixor(a, b)/__ixor__(a, b)—a = ixor(a, b)는a ^= b와 동등.
더 알아보기
functools— callable 객체에 대한 고차 함수와 연산.