# `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__()`와 동등합니다.

`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`를 반환합니다.

  버전 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)

  o 객체의 추정된 길이를 반환합니다. 먼저 실제 길이를 반환하려고 시도한 다음, `object.__length_hint__()`를 사용하여 추정치를 반환하려고 하고, 마지막으로 default 값을 반환합니다.

  버전 3.4에 추가.

`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`와 동등합니다.

  버전 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`와 동등합니다.