# `operator` — 함수로서의 표준 연산자

소스 코드: Lib/operator.py

`operator` 모듈은 파이썬의 내장 연산자에 해당하는 효율적인 함수 집합을 내보냅니다. 예를 들어, `operator.add(x, y)`는 `x+y` 표현식과 동등합니다. 많은 함수 이름은 특수 메서드에 사용되는 이름인데, 이중 밑줄이 없습니다. 이전 버전과의 호환성을 위해, 이들 중 많은 것은 이중 밑줄이 있는 변형을 가집니다. 이중 밑줄이 없는 변형이 명확성을 위해 선호됩니다.

함수는 객체 비교, 논리 연산, 수학 연산 및 시퀀스 연산을 수행하는 범주로 분류됩니다.

객체 비교 함수는 모든 객체에 유용하며, 이들이 지원하는 풍부한 비교(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)
operator.__lt__(a, b)
operator.__le__(a, b)
operator.__eq__(a, b)
operator.__ne__(a, b)
operator.__ge__(a, b)
operator.__gt__(a, b)

  a와 b 사이에 “풍부한 비교(rich comparisons)”를 수행합니다. 구체적으로, `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`와 동등합니다. 이러한 함수는 불리언 값으로 해석 할 수도 있고, 그렇지 않을 수도 있는 임의의 값을 반환 할 수 있음에 유의하십시오. 풍부한 비교에 대한 자세한 정보는 비교를 참조하십시오.

논리 연산도 일반적으로 모든 객체에 적용 할 수 있으며, 진릿값 검사, 아이덴티티 검사 및 불리언 연산을 지원합니다:

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.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의 비트별 논리곱(and)을 반환합니다.

operator.floordiv(a, b)
operator.__floordiv__(a, b)

  `a // b`를 반환합니다.

operator.index(a)
operator.__index__(a)

  정수로 변환된 a를 반환합니다. `a.__index__()`와 동등합니다.

  버전 3.10에서 변경: The result always has exact type `int`. Previously, the result could have been an instance of a subclass of `int`.

operator.inv(obj)
operator.invert(obj)
operator.__inv__(obj)
operator.__invert__(obj)

  숫자 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 숫자에 대해, `a * b`를 반환합니다.

operator.matmul(a, b)
operator.__matmul__(a, b)

  `a @ b`를 반환합니다.

  Added in version 3.5.

operator.neg(obj)
operator.__neg__(obj)

  obj의 부정(`-obj`)을 반환합니다.

operator.or_(a, b)
operator.__or__(a, b)

  a와 b의 비트별 논리합(or)을 반환합니다.

operator.pos(obj)
operator.__pos__(obj)

  양의 obj(`+obj`)를 반환합니다.

operator.pow(a, b)
operator.__pow__(a, b)

  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)

  `a / b`를 반환합니다. 여기서 2/3는 0이 아니라 .66입니다. 이것은 “실수(true)” 나누기라고 도합니다.

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)

  a의 값을 인덱스 b에서 제거합니다.

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__()`를 사용하여 추정치를 반환하려고 하고, 마지막으로 default 값을 반환합니다.

  Added in version 3.4.

The following operation works with callables:

operator.call(obj, /, *args, **kwargs)
operator.__call__(obj, /, *args, **kwargs)

  `obj(*args, **kwargs)`를 반환합니다.

  Added in version 3.11.

`operator` 모듈은 일반화된 어트리뷰트와 항목 조회를 위한 도구도 정의합니다. 이것은 `map()`, `sorted()`, `itertools.groupby()` 또는 함수 인자를 기대하는 다른 함수의 인자로 사용될 고속 필드 추출기를 만드는 데 유용합니다.

operator.attrgetter(attr)
operator.attrgetter(*attrs)

  피연산자에서 attr을 꺼내는 콜러블 객체를 반환합니다. 둘 이상의 어트리뷰트가 요청되면, 어트리뷰트의 튜플을 반환합니다. 어트리뷰트 이름은 점을 포함할 수도 있습니다. 예를 들어:

  - `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을 꺼내는 콜러블 객체를 반환합니다. 여러 항목이 지정되면, 조회 값의 튜플을 반환합니다. 예를 들어:

  - `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 메서드를 호출하는 콜러블 객체를 반환합니다. 추가 인자 및/또는 키워드 인자가 주어지면, 해당 인자도 메서드에 제공됩니다. 예를 들어:

  - `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

## 연산자를 함수에 매핑하기

이 표는 추상 연산이 파이썬 문법의 연산자 기호와 `operator` 모듈의 함수로 어떻게 대응되는지를 보여줍니다.

연산 | 문법 | 함수
--- | --- | ---
더하기(Addition) | `a + b` | `add(a, b)`
이어붙이기(Concatenation) | `seq1 + seq2` | `concat(seq1, seq2)`
포함 검사(Containment Test) | `obj in seq` | `contains(seq, obj)`
나누기(Division) | `a / b` | `truediv(a, b)`
나누기(Division) | `a // b` | `floordiv(a, b)`
비트별 논리곱(Bitwise And) | `a & b` | `and_(a, b)`
비트별 배타적 논리합(Bitwise Exclusive Or) | `a ^ b` | `xor(a, b)`
비트별 반전(Bitwise Inversion) | `~ a` | `invert(a)`
비트별 논리합(Bitwise Or) | `a | b` | `or_(a, b)`
거듭제곱(Exponentiation) | `a ** b` | `pow(a, b)`
아이덴티티(Identity) | `a is b` | `is_(a, b)`
아이덴티티(Identity) | `a is not b` | `is_not(a, b)`
인덱싱된 대입(Indexed Assignment) | `obj[k] = v` | `setitem(obj, k, v)`
인덱싱된 삭제(Indexed Deletion) | `del obj[k]` | `delitem(obj, k)`
인덱싱(Indexing) | `obj[k]` | `getitem(obj, k)`
왼쪽으로 시프트(Left Shift) | `a << b` | `lshift(a, b)`
모듈로(Modulo) | `a % b` | `mod(a, b)`
곱하기(Multiplication) | `a * b` | `mul(a, b)`
행렬 곱하기(Matrix Multiplication) | `a @ b` | `matmul(a, b)`
부정 (산술)(Negation (Arithmetic)) | `- a` | `neg(a)`
부정 (논리)(Negation (Logical)) | `not a` | `not_(a)`
양(Positive) | `+ a` | `pos(a)`
오른쪽으로 시프트(Right Shift) | `a >> b` | `rshift(a, b)`
슬라이스 대입(Slice Assignment) | `seq[i:j] = values` | `setitem(seq, slice(i, j), values)`
슬라이스 삭제(Slice Deletion) | `del seq[i:j]` | `delitem(seq, slice(i, j))`
슬라이싱(Slicing) | `seq[i:j]` | `getitem(seq, slice(i, j))`
문자열 포매팅(String Formatting) | `s % obj` | `mod(s, obj)`
빼기(Subtraction) | `a - b` | `sub(a, b)`
진릿값 검사(Truth Test) | `obj` | `truth(obj)`
대소비교(Ordering) | `a < b` | `lt(a, b)`
대소비교(Ordering) | `a <= b` | `le(a, b)`
동등성(Equality) | `a == b` | `eq(a, b)`
다름(Difference) | `a != b` | `ne(a, b)`
대소비교(Ordering) | `a >= b` | `ge(a, b)`
대소비교(Ordering) | `a > b` | `gt(a, b)`

## 제자리 연산자

많은 연산에는 “제자리(in-place)” 버전이 있습니다. 아래에 나열된 것들은 일반적인 문법보다 제자리 연산자에 대한 더 기본적인 액세스를 제공하는 함수입니다; 예를 들어, 문장 `x += y`는 `x = operator.iadd(x, y)`와 동등합니다. 또 다른 식으로는, `z = operator.iadd(x, y)`가 복합문 `z = x; z += y`와 동등하다고 말하는 것입니다.

이 예제들에서, 제자리 메서드가 호출될 때, 계산과 대입이 두 개의 분리된 단계에서 수행된다는 점에 유의하십시오. 아래 나열된 제자리 함수는 제자리 메서드를 호출하는 첫 번째 단계만 수행합니다. 두 번째 단계인 대입은 처리되지 않습니다.

문자열, 숫자 및 튜플과 같은 불변 대상의 경우, 갱신된 값이 계산되지만, 입력 변수에 다시 할당되지 않습니다:

    >>> a = 'hello'
    >>> iadd(a, ' world')
    'hello world'
    >>> a
    'hello'

리스트와 딕셔너리 같은 가변 대상의 경우, 제자리 메서드가 갱신을 수행하므로, 이후 대입이 필요하지 않습니다:

    >>> 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)
operator.__iadd__(a, b)

  `a = iadd(a, b)`는 `a += b`와 동등합니다.

operator.iand(a, b)
operator.__iand__(a, b)

  `a = iand(a, b)`는 `a &= b`와 동등합니다.

operator.iconcat(a, b)
operator.__iconcat__(a, b)

  a와 b 시퀀스에 대해, `a = iconcat(a, b)`는 `a += b`와 동등합니다.

operator.ifloordiv(a, b)
operator.__ifloordiv__(a, b)

  `a = ifloordiv(a, b)`는 `a //= b`와 동등합니다.

operator.ilshift(a, b)
operator.__ilshift__(a, b)

  `a = ilshift(a, b)`는 `a <<= b`와 동등합니다.

operator.imod(a, b)
operator.__imod__(a, b)

  `a = imod(a, b)`는 `a %= b`와 동등합니다.

operator.imul(a, b)
operator.__imul__(a, b)

  `a = imul(a, b)`는 `a *= b`와 동등합니다.

operator.imatmul(a, b)
operator.__imatmul__(a, b)

  `a = imatmul(a, b)`는 `a @= b`와 동등합니다.

  Added in version 3.5.

operator.ior(a, b)
operator.__ior__(a, b)

  `a = ior(a, b)`는 `a |= b`와 동등합니다.

operator.ipow(a, b)
operator.__ipow__(a, b)

  `a = ipow(a, b)`는 `a **= b`와 동등합니다.

operator.irshift(a, b)
operator.__irshift__(a, b)

  `a = irshift(a, b)`는 `a >>= b`와 동등합니다.

operator.isub(a, b)
operator.__isub__(a, b)

  `a = isub(a, b)`는 `a -= b`와 동등합니다.

operator.itruediv(a, b)
operator.__itruediv__(a, b)

  `a = itruediv(a, b)`는 `a /= b`와 동등합니다.

operator.ixor(a, b)
operator.__ixor__(a, b)

  `a = ixor(a, b)`는 `a ^= b`와 동등합니다.